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
- Example Application – Using Jersey and Spring Together
- Create a simple RESTful Webservice with Jersey and Spring, Rafael Sobek
- Jersey-Spring API
- Jersey and Spring, Paul Sandoz
- Jersey, Spring, and JPA, David Sells
- An Introduction to Creating RESTful Web Services Using Jersey and Java, Bruce Phillips Blog
- An Example of Using Jersey RESTFul Web Services, Java, Ajax, and JavaScript, Bruce Phillips Blog
- JAX-RS, the Java API for RESTful web services
- jsr311-api 1.0 API
- Jersey, Sun's Reference Implementation for JAX-RS
- RESTful Web Services Developer's Guide, Sun MicroSystems
- Jersey Test Framework, Naresh's Blog
- Introduction to the Spring Framework
- Spring Framework
- Spring Framework Bean Scope
There are no comments for this entry.
[Add Comment]