A couple years back, while I was working through some slides to teach a Java class (mostly Java EE and Spring) I created a REST web service using Spring WebMVC. I wrote a few posts (starting here) about how it works.
I’ve recently been teaching that class again, updating to later versions of Java and later versions of libraries. When I got to the Spring WebMVC class, I wanted to teach it, because I still think it’s a good choice for an application that uses the Spring framework (because it integrates with Spring dependency injection). But of course now we have the Java API for RESTful Web Services (JAX-RS) as an option.
So I’ve adapted the previous example to JAX-RS. Fortunately, some of the little tricks used with the Spring WebMVC application still apply.
JAX-RS divides the work of the REST web service amongst one or more provider classes. Each provider class handles a set of paths within the whole application, and each provider class can have multiple methods that handle specific paths and HTTP methods.
Provider classes are plain old Java objects (POJOs), using annotations to specify JAX-RS parameters. Here is the provider class for this application.
The example illustrates both
POST HTTP methods, and illustrates
passing in parameters, either via components of the URL or via the request
The key annotations used above are:
@Path: Adds a path component for matching the incoming URL. Path components are cumulative, so the class annotation and the method annotation work together. The path can contain templates used to supply parameters.
@GET: Specifies a method that handles HTTP GET requests.
@POST: Specifies a method that handles HTTP POST requests.
@PathParam: Associates a template in the URL with a method parameter.
Not illustrated in this example is
@QueryParam, which works similar to
@PathParam but instead matches a form input (either encoded in the URL as
?name1=value1&name2=value2 pairs, or in a
name=value list with linebreaks
in the request body).
For those familiar with Spring WebMVC, note that the annotations are quite
similar. Also note that some annotations, like
@ResponseBody to specify that the request body should be converted to a
parameter, or the returned Java object should become the response body, are
assumed rather than specified.
The JAX-RS application class allows, among other things, customizing which packages are scanned for providers.
ResourceConfig is a Jersey class that extends from the standard JAX-RS
Application class and provides package scanning and other helper
applications. It also provides an implementation for the standard
getSingletons() methods that we would otherwise have to
While it is possible with Servlet 3.0 to deploy applications without use of a deployment descriptor, it makes it easier to connect Jetty with Jersey when running using the Maven Jetty plugin.
This configuration uses a servlet provided by Jersey to delegate to the JAX-RS application class we defined earlier. This also allows us to specify the first component of the path for JAX-RS services (to keep them distinct from static files, which we also want to serve).
Deploying and Running
The Maven POM file handles building a JAR (for a standalone application, discussed
in the next post), and a WAR (for deploying to a Servlet container). It also
includes the Maven Jetty plugin, allowing us to run the application from the
command line using
We list a dependency on the Jersey plugin for Jackson, so we can move between
Java and JSON. However, the client must specify the header
otherwise, the server defaults to XML. Also, when supplying data to the server for
the POST request, the client must also specify a
The next post will provide detail on running the service in a regular Java application using an embedded Jetty server.