0
votes

I am trying to integrate jersey to an existing Spring application (Spring 2.5.5). Jersey is working fine, but however when I AutoWire an existing spring bean, the object is null. Below is my web.xml

<servlet>
    <servlet-name>fs3web</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.fl.fs3.api;org.codehaus.jackson.jaxrs</param-value>
    </init-param>
    <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-mapping>
    <servlet-name>fs3web</servlet-name>
    <url-pattern>/fs3/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

And, here my application context xml (obviously this is not complete, since this is a huge application, there is much more bean definitions): TestPojo is my bean I would like to autowire to my jersey resource.

<context:annotation-config />  
<aop:aspectj-autoproxy/> 
<context:component-scan base-package="com.fl.fs3.api,com.fl.fs3.integration.*.web"/>    

Both my jersey resource class and POJO class is in package com.fl.fs3.api

@Component
@Path("/v1/site")
public class SitesApiControllerV1 {
    @Autowired TestPojo  testPojo;

    @GET
    @Path("/{folderName}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getSite(@PathParam("folderName") String folderName) {
         System.out.println("pojo obj:" + testPojo);
         return Response.ok("info for " + folderName).build();
}
}

@Component
public class TestPojo {

}

When I start my tomcat, I do not see the expected line in logs: INFO: Registering Spring bean, hello, of type ..... as a root resource class When I invoke my service /v1/site/xyz, testPojo object is null.

However, before integrating this to my existing project, I did a sample jersey+spring application, and it worked perfectly. I was able to see 'Registering Spring bean' line in logs.

Any help is appreciated.

1
Are you really interested in using this quite old version of Spring (2.5.5) though Spring 3.2.2 was released a few months ago (and even newer versions are about to be released or may have been released)? You're likely facing serious problems in the future as you proceed.Lion
Where and how is the Spring context initialized? I don't see a reference to it in the web.xml.user1907906
@Lion We tried upgrading to spring 3.2, but we had some problems with that. Since this is a critical application, we are not inclined to upgrade to spring 3.2.2 as of now. So, need to work with 2.5.5 for now.Harish BN
@Tichodroma the app is called fs3web, so the fs3web-servlet.xml is the application context loaded. The spring application itself is working fine.Harish BN

1 Answers

0
votes

Try this, it may be more simplified:

Load spring through web.xml like shown below as normal spring confifuration:

<servlet>
    <servlet-name>project-spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:project-spring-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>project-spring</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

Now load your jersey Resources through Application as shown below:

@ApplicationPath("/rest")
public class ResourceLoader extends Application
{

    /* (non-Javadoc)
     * @see javax.ws.rs.core.Application#getClasses()
     */
    @Override
    public Set<Class<?>> getClasses()
    {
        Set<Class<?>> classes = new HashSet<Class<?>>();
        loadResourceClasses(classes);
        return classes;
    }

    private void loadResourceClasses(Set<Class<?>> classes)
    {
        classes.add(StudentResource.class);
    }
}

Then in your resource:

@Path("student")
class StudentResource
{
    private StudentService studentService;

    StudentResource(@Context ServletContext servletContext)
    {
        ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        this.transactionService = applicationContext.getBean(StudentService .class);
    }
}

There you go. Spring has been configured with all dependency injections with Jersey!