Exponer servicios REST y HttpInvoker en una sola clase

Hasta el año 2015, momento del nacimiento de Sngular, el nombre de "s|Software" era "Medianet Software"

Javier Onsurbe ilustra el modo en el que se pueden exponer servicios de la capa de backend por distintos protocolos, de una manera fácil, sencilla y configurable.

El principal valor de esta solución es que permite exponer un mismo servicio desde una sola clase pero en distintos protocolos, dotando a la arquitectura de un grado de flexibilidad adicional, y la sencillez añadida de tenerlo todo en una misma clase.

Este es el artículo en su blog:

Cuando uno tiene que definir una plataforma de servicios en un sistema se encuentra con la decisión de cual va a ser el protocolo en el que publicarlos ya que cada decisión tiene sus pros y sus contras y principalmente se utiliza el siguiente criterio

  • Si los servicios van a ser públicos habría que usar un protocolo basado en texto para facilitar la integración, p.e.- REST con Json.
  • Si los servicios van a ser internos a la organización es más interesante utilizar un protocolo binario ya que podemos proporcionar el cliente, p.e.- HTTP Invoker.

Pero que pasa si van a ser internos y externos? Aquí caben dos decisiones, o bien los publicamos con REST todos o bien los publicamos en los dos protocolos. Pero si los publicamos en los dos protocolos hay que mantener una coherencia entre los interfaces de un protocolo con el del otro o bien utilizar la misma clase java para ambos

Hace poco alguien me comento que no era posible utilizar la misma clase Java para publicar en ambos protocolos, aquí vamos a ver como se puede hacer.

Para empezar, necesitamos un proyecto web con todas las dependencias necesarias las cuales son:

    [code lang=xml]
    org.springframework
    spring-core
    3.1.4.RELEASE
   

   
    org.springframework
    spring-context
    3.1.4.RELEASE
   

   
    org.springframework
    spring-aop
    3.1.4.RELEASE
   

   
    org.springframework
    spring-webmvc
    3.1.4.RELEASE
   

   
    org.aspectj
    aspectjrt
    1.7.2
   

   
    org.aspectj
    aspectjweaver
    1.7.2
   

    [/code]

Luego necesitaríamos configurar el fichero web.xml para permitir la publicación de la parte REST:

    [code lang=xml]
   
    characterEncodingFilter
    org.springframework.web.filter.CharacterEncodingFilter
   
    encoding
    UTF-8
   

   
    forceEncoding
    true
   

   

   
    characterEncodingFilter
    /*
   

   
   
    httpMethodFilter
    org.springframework.web.filter.HiddenHttpMethodFilter
   

   
    httpMethodFilter
    /*
   

   
   
    log4jConfigLocation
    classpath:log4j.xml
   

   
   
    org.springframework.web.context.ContextLoaderListener
   

   
    org.springframework.web.util.Log4jConfigListener
   

   
    org.springframework.web.context.request.RequestContextListener
   

   
    Multiprotolo
    org.springframework.web.servlet.DispatcherServlet
   
    contextConfigLocation
   
   

   

   
    Multiprotolo
    /
   

    [/code]

Con esto ya tendríamos la infraestructura necesaria para montar un servicio REST+JSon utilizando SpringMVC. Ahora crearíamos el controller:

[code lang=java]
@Controller(value = "hello")
public class HelloServiceImpl implements HelloService
{[/code]

E implementamos un método a publicar como servicio:


[code lang=java]
@Override
@RequestMapping(value = "/rest/hello/{user}")
@ResponseBody
public String helloUser(@PathVariable("user") String user){
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json;
charset=utf-8"); return "Hello "+user; }
[/code]

Solo nos faltaría para publicarlo agregar la correspondiente configuración al contexto de Spring:

    [code lang=xml]
   
   
    [/code]

Con esto estaría hecha la parte mvc, fácil, rápido y limpio.

Ahora faltaría publicar esto mismo utilizando HTTP Invoker, si se observa la declaración anterior del controller se ve que esta implementa un interfaz, este interfaz es obligatoria para publicar HTTP Invoker y deben estar incluidos en el mismo todos los métodos del controller que tengamos publicados.

Para ello habría que publicar dicho bean usando el HttpInvokerServiceExporter y que dicho exporter referencie al bean del controller.

[code lang=xml] class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">

value="es.onsurbe.services.rest.HelloService"/>


[/code]

Con esto y estaría publicado el mismo servicio en 2 protocolos distintos.

Se puede descargar el proyecto completo el cual incluye los test para probarlo en mi repositorio hg en bitbucket

Ver artículo original: Como proveer servicios HttpInvoker y REST en una misma clase

Últimos posts