Using Jersey (RESTful Web Services) and Spring (Dependency Injection) Together

Introduction

I worked on a project that uses Jersey RESTful web services that depend on other classes to do the actual work.  For example a web service that uses a data access object to get information out of a data repository.  Since I like to use Spring to manage dependencies between classes, I needed to learn how to integrate Spring and Jersey.

This article assumes you know how to use Jersey and Spring (if you don't check out all the references below).  In this article I provide a simple example application that demonstrates how to use Spring to manage dependencies for a Jersey RESTful web service.  Please note that the information in this article is based on excellent blogs written by Paul Sandoz, (implementation lead for RESTful web services API), Rafael Sobek, David Sells, and others (see references).  This article is just a simple introduction to using Jersey and Spring together.  See the references for more detail.

Jersey-Spring API

Jersey provides a Spring integration API.  The class you'll need to include in your web.xml is:

com.sun.jersey.spi.spring.container.servlet.SpringServlet

You can use this class in your web.xml as the Servlet that will setup and manage your web service resources as Spring-managed beans.  Per the JavaDoc for this class you can use either "XML-based configuration or auto-wire-based configuration" for setting up your web service resource as a Spring-managed bean.  In my example application, I used XML-based configuration.

Below is the extract from the example application's web.xml that sets up this Servlet.


<servlet>
<servlet-name>Jersey Spring</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>name.brucephillips.hellows.resources</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Spring</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

Example Application

The example application (download the archived Eclipse – Maven project) is based on the example provided in my first article on using Jersey to create a RESTful web service.  

You can import the archived Eclipse project into Eclipse (I used Eclipse version 3.5 with the Maven 2 plugin) and then run the project using a Tomcat server.  Since the project uses Maven you can also run the example by opening a command (terminal) window, navigate to where you unzipped the download (the directory where pom.xml is located) and type mvn jetty:run.  When you see [info] Started Jetty Server open a web browser and go to http://localhost:8080/helloWS/index.html.  When you're done type Control-C to halt the Jetty Servlet container.

The example application provides some links that call the RESTful web service (class HelloResource) and displays the text returned.  The web service class is using another class (HelloService) to get the hello data.  This is the dependency that is being managed by Spring. 

In the applicationContext.xml I set up the beans for Spring to manage as follows.



<bean id="helloService" class="name.brucephillips.hellows.service.HelloServicePlain" />

<bean id="helloResource" class="name.brucephillips.hellows.resources.HelloResource">

<property name="helloService" ref="helloService" />
    
</bean>

After deploying the application to a Servlet container and starting up the container, you'll see numerous info and debug messages.   Two messages show that Spring is managing the HelloService and HelloResource beans:

Creating shared instance of singleton bean 'helloService'
Creating shared instance of singleton bean 'helloResource'

Note that Spring is managing these beans as singletons.  This means that each request will get the same bean.  In my example application this is fine.  If you need each request to receive a new instantiation of the class then you need to use the request scope for your bean.  See the bean scope definitions in the Spring documentation.  If you do use request scope beans then you must add this listener to your web.xml:


<listener>

<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>

</listener>

Summary

This article discusses how to use Jersey (for RESTful web services) and Spring (for dependency injection) together.  Combining these two powerful technologies makes developing robust web services easier. 

One area I need to research further is how to unit test a web service that has its dependencies managed by Spring.  My previous unit tests used the Jersey test framework but I've not yet been able to figure out how to use this test framework when the web service needs Spring to inject its dependency.

See this blog article for newer information about how to test a RESTful Web Service that uses the Jersey framework:
/blog/index.cfm/2009/9/14/Unit-Testing-Jersey-RESTful-Web-Services-That-Also-Use-The-Spring-Framework

References

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact Blog Owner