Jersey and Spring
By edort on Apr 13, 2009
by Paul Sandoz
Jersey is an open-source, production-ready reference implementation of JAX-RS, the Java API for RESTful Web Services (JSR-311). JAX-RS is an annotation-driven API that makes it easy to build Java-based RESTful web services that adhere to the REST architectural style. The JAX-RS API is standardized by the Java Community Process. The JAX-RS API is currently at version 1.0 and Jersey is at version 1.0.2.
An earlier Tech Tip, Implementing RESTful Web Services in Java, introduced RESTful Web Services, JAX-RS, and Jersey. It also showed how you can write RESTful web services that conform to the JAX-RS specification. Other tips on Jersey-related topics described how to configure JSON for RESTful web services in Jersey 1.0 and how to consume RESTful web services with the Jersey client API.
In this tip, you will learn how to use Jersey's integrated support for Spring, a framework for building and running enterprise Java applications. You'll learn how to configure Spring with Jersey and use Jersey's Spring-related features. The tip assumes that you are familiar with Spring concepts. If not, refer to the Spring Tutorial.
Creating a Basic Web Application
To demonstrate Jersey's Spring-related features, you'll first create a simple web application, one that does not use Spring and then change it to use Spring. Let's use the Maven 2 software project management tool to build the simple web application. If you're not familiar with Maven, see Welcome to Maven and Building Web Applications with Maven 2.
First, create a Maven 2 project by running the following Maven 2 archetype plugin in a command line:
In response, Maven 2 will prompt you to choose an archetype, that is, a Maven 2 project template, from the archetypes
listed in the archetype catalog,
archetype-catalog.xml, at URL http://download.java.net/maven/2:
jersey-quickstart-webapp. You will then be prompted for a group ID and an artifact ID. Enter
example.jersey.spring for the group ID and
example-spring-jersey for the artifact ID.
Accept the default values for the other prompts.
After you confirm the inputs, Maven 2 creates a new subdirectory called
example-spring-jersey, which contains
a template for the new Jersey-based web application. Figure 1 shows the expanded structure of the
Figure 1. Expanded Structure of the
Maven 2 also creates a Project Object Model (POM) file,
pom.xml, which contains an XML representation of the
Maven project. You can find the
pom.xml file in the
If you navigate below the
example-spring-jersey directory to
src/main/java/example/jersey/spring, you'll see a Java class named
represents a resource used in the application. You'll also find a
web.xml file for the web application
Let's build, deploy, and test the web application to see if it works. To build the application, go to the
example-spring-jersey directory and enter the following command:
In response, Maven 2 compiles the source code and creates an
for the application.
To deploy the application, GlassFish V3 Prelude must be running. Start GlassFish V3 Prelude if it isn't already running. To start GlassFish V3 Prelude, enter the following command:
<GF_install_dir/bin> is the directory where you installed GlassFish v3 Prelude.
Deploy the application to GlassFish v3 Prelude using the following command:
Finally, you can verify that the deployed application runs by using the command line tool, curl, as follows:
In response, you should see the following output in the command window:
You can also verify the application by pointing your browser to the URL http://localhost:8080/example-spring-jersey/webresources/myresource. You should see the following text displayed on the page: Hi there!
Transforming the Web Application to Use Spring
Now let's change the web application to use Spring. To do that, you need to take the following actions:
- Modify the
pom.xmlfile to include Spring dependencies.
- Create a Spring application context configuration file.
- Modify the
web.xmlfile to declare the Spring configuration.
- Modify the root resource class to be a Spring component.
pom.xml File: Recall that one of the files generated when you
created the Maven 2 project for the web application is a
pom.xml file that
represents the Maven project. Replace the contents of the
pom.xml file with
the content shown here.
The replacing code simplifies the Maven configuration to only use the required dependencies for this example. Note especially the following code, which adds the Jersey Spring dependency, using the jersey-spring module:
Create a Spring Application Context Configuration: The Spring application context configuration file
specifies an application's configuration for initialization by Spring. You need to create a Spring application context
configuration file for the web application. Create a file
applicationContext.xml and put it in the
src/main/resources directory. The file should have the following content:
This configuration directs Spring to use autowiring with Spring-based annotations and to scan for Spring-based resources
in the Java
package example.spring.jersey. Autowiring is a feature in Spring that allows it to introspect
bean classes for dependencies so that you do not have to explicitly specify bean properties or constructor arguments.
web.xml File: Replace the contents of the
web.xml file with
the content shown here.
The following code in the updated
web.xml file declares the Spring application context configuration,
created earlier as a servlet context parameter:
The updated content also declares two listeners. The first configures Spring and the second configures Spring for use with the request scope for Spring beans.
Then, the file declares the Jersey Spring servlet, which supports the Jersey integration with Spring.
Modify the Root Resource Class: Modify the
MyResource.java file in the
src/main/java/example/jersey/spring directory with the following content:
@Component annotation declares that the class is a Spring bean class.
@Scope("request") annotation declares that instances of this class will be instantiated
within the scope of the HTTP request. This highlights a difference between the default scopes for JAX-RS or Jersey
and Spring. The default scope for JAX-RS is per request. By comparison, the default scope for Spring is a singleton,
that is, one instance per web application. See Supported Scopes for more information about the
scopes that Jersey supports.
MyResource root resource class is functionally equivalent to the root resource class that you originally
created, but it's now Spring-enabled.
Verify that the Spring-enabled web application deploys and executes by entering the following commands in a command line:
After the Spring-enabled web application is successfully deployed, you should see output
similar to the following in the server.log
Notice the final line that begins "Registering Spring bean". This is output from Jersey. Jersey knows that the
MyResource is a root resource class and also a Spring bean class. No Jersey-specific configuration was
required to register root resource classes, as was the case in the
web.xml for the original version of the
Because Spring is used to register Spring beans, in this case using autowiring, Jersey leverages Spring to perform registration rather that requiring duplicate registration. It is possible to intermix Spring-managed and Jersey-managed root resource classes by using Jersey's registration mechanism. It does not matter if both Spring and Jersey find the same class -- only one reference to the class will be managed appropriately.
Jersey supports the following Spring scopes:
- Request. Scopes a single Spring bean definition to the lifecycle of a single HTTP request, that is, each HTTP request has
its own instance of a Spring bean created from a single Spring bean definition. This scope requires that you declare the Spring
RequestContextListenerservlet context in the
web.xmlfile for the web application.
- Singleton. Scopes a single Spring bean definition to a single object instance per web application.
- Prototype. Scopes a single Spring bean definition to multiple object instances. A new Spring bean instance is created for each request for that specific bean.
You can inject Jersey artifacts into fields of Spring bean instances according to the scoping rules. If the scope is prototype, then the scoping rules for request apply. If Jersey does not recognize the scope, then it assumes a scope of singleton for the purpose of injection.
For example, you can modify the
MyResource class in the Spring-enabled Web application to include an
@QueryParam for injection. Here is what the modified class looks like:
In response, Jersey should inject the information into the Spring bean in request scope, that is, per request. To test that, you can redeploy and execute the updated application by entering the following commands in a command line window:
The application should return "Hi there! curl" in the output. If it does, this verifies that Jersey can correctly inject information into the Spring bean per request.
This tip showed you how to use some of Jersey's Spring-related features. But there are other useful elements to Jersey's support for Spring. Some of the these are:
- You can take advantage of the JAX-RS support for hierarchical URI path matching to further match a URI path that
was not already matched by a root resource. This means that you can include a subresource locator method in a resource
to return an instance of a newly created Spring bean class. You use the Jersey
ResourceContextclass to obtain the instance.
You can inject Spring beans into JAX-RS-based methods. You do this with the Jersey
- You can use Jersey Spring-based Aspect-Oriented Programming (AOP).
- You can have Spring instantiate a resource class, but have Jersey manage the resource class's lifecycle.
For more information on Jersey and Spring, see the following resources:
- Jersey Project
- Getting Started With Jersey
- Jersey-Spring 1.0.2 API Overview
- Jersey-Spring Container Servlet Package
About the Author
Paul Sandoz is the co-spec lead and implementation lead for JSR 311: Java API for RESTful Web Services. He has participated in the W3C, ISO, and ITU-T standards organizations and contributed various performance-related technologies and improvements to the GlassFish web services stack, particularly in standardization, implementation, integration, and interoperability of Fast Infoset.
2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*
Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009, and save $200 off a Conference Pass or Conference Plus Pass. Register now at http://java.sun.com/javaone.