Integrar Jersey y Spring

Supongamos que ya tenemos nuestro proyecto con el modulo de Jersey integrado y funcionando.

Tenemos el servlet de Jersey configurado y funcionando, pero vamos a meter Spring en nuestro proyecto
para poder utilizar sus ventajas como contenedor , integrador y gobernador.

Spring va a gobernar nuestra aplicacion, asi que debemos configurarlo para que gobierne tambien la parte
de Jersey.

Jersey ofrece herramientas para integrar con Spring, estas se encuentran en la libreria
com.sun.jersey.contribs . Para descargar esta dependencia (si nuestro proyecto esta integrado con maven)
hace falta meter en nuestro pom.xml esto:

    <!-- Dependencias utils para integrar JErsey y Spring -->
   <dependency>
       <groupId>com.sun.jersey.contribs</groupId>
       <artifactId>jersey-spring</artifactId>
       <version>1.8</version>
   </dependency>
 
Por defecto jersey-spring trabaja con Spring 2.5.6, pero si   quieres usar la libreria integrando con spring 3 es necesario meter estos excludes:
   <dependency>
       <groupId>com.sun.jersey.contribs</groupId>
       <artifactId>jersey-spring</artifactId>
       <version>1.8</version>
       <exclusions><!--  Es necesario quitarlas para poder trabajar con  spring 3 -->
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aop</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>

        </exclusions>
   </dependency>

Ademas es necesario especificar al menos estas depedencias de Spring3:

        <!--  Spring dependencies-->
        <dependency> <!--esta es el core normal-->
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
             <version>3.1.2.RELEASE</version>
        </dependency>
        <dependency> <!-- Esta es necesaria para funcionalidad web-->
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
             <version>3.1.2.RELEASE</version>
        </dependency>


   Al descargar esta dependencia obtendremos una nueva clase (servlet) que integra jersey con Spring.
   Esta clase se llama com.sun.jersey.spi.spring.container.servlet.SpringServlet .
  
   Por lo tanto, el servlet de Jersey (que ya teniamos en el proyecto) debemos cambiarle la clase, para que instancie un servlet de tipo SpringServlet.
  
   Ahora la configuracion de Jersey en el web.xml quedara asi:
  
       <!--Servlet de JAx RS jersey Configuracion-->
    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <!-- Servlet de jersey, pero que tien funcnionalida que integra con spring -->
        <servlet-class>    com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>

        <!--esta propiedad le dice donde estan los servlets que debe buscar anotaciones-->
        <init-param>
          <param-name>com.sun.jersey.config.property.packages</param-name>
          <param-value>org.dppware.facade</param-value>
        </init-param>
        <!-- Le dice cual es el directorio raiz de las jsp, por si se devuleve por viewable-->
        <init-param>
            <param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
            <param-value>/WEB-INF/jsp</param-value>
        </init-param>
        <!-- que use json-->
        <init-param>
             <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
           <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   
        <!-- Servlet de JAx RS jersey , escuchador peticiones-->
      <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/resources/*</url-pattern>
      </servlet-mapping>
     
     
     
      Vemos, que no hemos cambiado nada en la configuracion que teniamos antes de jersey, basta con cambiar la  <servlet-class> para que apunte a la nueva clase SpringServlet.
     
      Como esta clase integra con Spring, al instanciarse el SpringServlet , aparte de buscar la configuracion
      de Jersey e instanciar sus servicios, tambien buscara si debe instanciar algun contexto en la aplicacion.
     
      Para ello (como siempre )Spring busca su fichero de definicion de beans. Para indicarle donde debe buscarlo debemos especificar la propiedad ContextConfigLocatiodentro de nuestro web.xml:
     
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:appCtx/server-context.xml</param-value>
    </context-param>
     
      (En este caso he creado un archivo dentro de appCtx y ahi he definido los beans de forma normal)
      Como queremos que Spring meta los servicios de Jersey  dentro de su contexto, es necesario definir esos servicios   como beans:
     
    Asi, si tenia los servicios Jersey en
        <init-param>
          <param-name>com.sun.jersey.config.property.packages</param-name>
          <param-value>org.dppware.facade</param-value>
        </init-param>
         
   
    Ahora voy a decirle a Spring que busque los beans de esa carpeta tambien en el contexto (server-context.xml)
      <context:component-scan base-package="org.dppware.facade"/>
      (Para usar esto es necesario anotar las classes con @Component )
     
      Otra alternativa es definir los beans a mano en el xml:
     
        <bean id="genericFacadeBean" class="org.dppware.facade.impl.GenericFacade">
              ...configuracion que queramos de spring, ref otros beans, , etc...
        </bean>   
   
     
      El ultimo paso es crear un listener de Spring, que escuche cuando se instancia el contexto
      y asi poder crear los beans de jersey e integrarlos en su contexto. Para ello, añadimos este listener:
     
      <listener>
          <listener-class>
                org.springframework.web.context.ContextLoaderListener
        </listener-class>
   </listener>
     
Bueno, con esto ya hemos metido los servicios de Jersey como beans en el contenedor.


    Ahora es necesario configurar Spring para que cuando vengan peticiones por Request, sepa redirigir
    al servicio Jersey que corresponda. Para ello basta con poner otro listener:
   
    <listener>
          <listener-class>
                org.springframework.web.context.request.RequestContextListener
        </listener-class>
   </listener>
     
      Con este listener el SpringServlet sabra a que servicio Jersey debe redirigir la peticion.



Pues nada, espero te haya ayudado.
     
     
     
     
     
 

Comentarios

Entradas populares de este blog

Reiniciar usuario de SVN Subversion

Subir campos Blob a BBDD (Oracle) con Java

Reproducir mp3 con Java