http://www.developer.com/

Back to article

JAX-RS: The Java API for RESTful Web Services


October 14, 2009

Introduction

JAX-RS (JSR 311), the Java API for RESTful web services, has had a profound effect on the architecture and design of web services. It was inspired by Roy Thomas Fielding's dissertation on the "Design of Network-based Software Architectures', in which he introduced the REST (Representational State Transfer) concept.

This introductory article to JAX-RS reviews two popular JAX-RS frameworks, Jersey and Apache CXF, and provides some basic examples that illustrate how to build, deploy, and execute RESTful web services. Before diving into the formal definition of REST, let's walk through the basic concepts required to understand REST.

You also should review Java annotations (part of JDK 1.4) and the Maven configuration and build tool, if you are not familiar with them already.

What Is REST?

The acronym REST (Representational State Transfer) refers to an architectural style for distributed hypermedia systems. (The term hypermedia refers to a combination of text, hyperlinks, graphics, audio, and video that creates an interactive medium of information. A network-distributed hypermedia system is a system of interlinked hypertext documents accessed via the Internet, such as the World Wide Web.) REST proposes a set of architectural principles, including client-stateless-server communication, uniform interface, separation of concerns and layered systems (click here for definitions of these principles). When applied as a whole to web services, the resulting systems generally achieve high performance, scalability, low/simplified component interactions, enforced security, and encapsulation of legacy systems.

JAX-RS Terminology

A resource class is a Java class annotated with JAX-RS annotations to represent a web resource. A root resource class is a POJO (plain old Java object) that is annotated with @Path, has at least one method annotated with @Path, or a request method designator such as @GET, @PUT, @POST, or @DELETE to handle requests on the corresponding resource.

Resource methods are request methods of a resource class. Annotated with @Path, they handle resource-specific operations: creating, reading, updating, and deleting resources. When a request method designator is used on resource methods, it is referred to as a sub-resource method. Methods not annotated with resource method designators are referred to as sub-resource locators. We will look at examples later in the article.

JAX-RS API and Implementation Details

JAX-RS is divided into three packages:

  • javax.ws.rs: High-level interfaces and annotations
  • javax.ws.rs.core: Low-level interfaces and annotations
  • javax.ws.rs.ext: Extensions to the types supported by the JAX-RS API

Here's what you need to know when implementing JAX-RS:

  • Root resource classes are instantiated by the JAX-RS runtime and must have a public constructor. By default, the lifecycle of root resource classes is per-request (an instance created every time the request URI path matches the root resource).
  • Resource methods should have one of the following return types: javax.ws.rs.core.Response, javax.ws.rs.core.GenericEntity, void or any other Java type, and be declared public. These return types are mapped appropriately into status codes by the JAX-RS Provider. For example, a return type of void is mapped into the 204 status code.
  • The user can throw any checked or unchecked exceptions (javax.ws.rs.WebApplicationException) inside a sub-resource method or sub-resource locator.
  • Implementations of javax.ws.rs.ext.MessageBodyWriter and javax.ws.es.ext.MessageBodyReader are responsible for serializing and deserializing between stream and Java types.

REST Frameworks

Let's look at two popular REST frameworks that provide standard ways for building RESTful services in Java:

  • Jersey: Sun's open source, production-quality reference implementation for JAX-RS
  • Apache CXF: Apache's Java API for RESTful web services

Jersey Framework

Jersey supports the annotations defined in JSR-311 to enable you to build RESTful web services that are simple and lightweight. The JAX-RS API provides a set of annotations and associated classes/interfaces that you can use to expose POJOs as web services.

Jersey also provides additional functionality beyond the JAX-RS API, including support for JavaScript Object Notation (JSON), Spring framework integration, and the Web Application Description Language (WADL).

A Simple JAX-RS Web Service with Jersey

Let's build a simple web service to demonstrate the use of annotations in JSR 311. The following example uses the Grizzly Web Container in Eclipse 3.3.2 with the plugin for Maven 2.0.9 installed. You need to have JDK 1.5 or higher installed to follow along.

  1. Create a simple Maven project in Eclipse (3.3.2) using the configuration below. Among other things, Maven creates a POM and the project myrestapp.



    Click here for larger image

  2. Add the appropriate dependencies, plug-ins, and repositories as listed here to the POM that you generated in Step 1. Make sure you have included a dependency for Jersey Server and Grizzly Server.
  3. Create a package com.mycompany.resources in the project and add a root resource class (RestByExampleResouce.java) that contains implementations for sub-resource methods in the resources package. We will discuss the methods later in the article.
  4. Implement a Java class (DeployRestByExample.java) in the myrestapp package to deploy the root resource (RestByExample.java) to the Grizzly web container programmatically using Grizzly-specific classes such as com.sun.grizzly.http.SelectorThread. You can accomplish this in other ways as well. A web service may extend the Application class to declare root resource and provider classes. Here is an example:



    Click here for larger image

    Alternatively, you could reuse the Jersey implementation com.sun.jersey.api.core.PackagesResourceConfig, which scans for root resource and provider classes given a classpath or a set of package names. Here is an example:



    Click here for larger image

  5. Implement a JUnit TestJersey.java using the Jersey Client API. Add it to the myrestapp package under src/test/java, as shown here.

  6. Open the Run Dialog within Eclipse (Run->Open RunDialog) to create a new configuration on a Maven build with clean compile install test as goals. Hit the Run button at the bottom to compile and install the JAX-RS application in the Maven repository.
  7. Run the DeployRestByExample.java class as 'Java Application' and you will see a grizzly bear staring at you!

Type in the URI http://localhost:9998/restbyexample in your favorite browser to try the new web service you just implemented. Remember that URI names are case-sensitive.

JAX-RS Annotations

JAX-RS annotations are runtime annotations. Let's look at some of the important ones that you implemented in the previous example.

  • @Path identifies the URI path that a resource class or class method will service. It may be used on classes. The classes that use it are referred to as root resource classes. It may also be used on methods of root resource classes. In the Jersey example, RestByExampleResouce.java was hosted at the URI path '/restbyexample'.
  • @PathParam extracts URI path parameters from the request URI, where the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation. In the Jersey example, the sub resource method getUserName() has an annotation @GET @Path("users/{name}"). It responds to the URI http://localhost:9998/restbyexample/users/xx by returning the text: You asked for xx
  • @GET indicates that the annotated method responds to HTTP GET requests. In the jersey example, the sub resource method doGetAsHtml() served to process HTTP GET requests for the media type text/html. It produces "Welcome to JAX-RS tutorial" for the URI http://localhost:9998/restbyexample.
  • @PRODUCES specifies the MIME media types of representations a resource will produce for a client. In the Jersey example, the sub resource methods doGetAsText() and doGetAsHtml() produce representations identified by the MIME media types text/plain and text/html, respectively.
  • @CONSUMES specifies the MIME media types of representations that a resource can consume from a client. In the Jersey example, the sub resource method doPostMimeFormEncoded() will consume representations identified by the MIME media type application/x-www-form-urlencoded.
  • @FormParam extracts information as form parameters POSTed by HTML forms from a request representation of MIME media type application/x-www-form-urlencoded. In the Jersey example, the sub resource method doPostMimeFormEncoded() will retrieve the form parameter 'whoami' when the form is posted with the action "http://localhost:9998/restbyexample/formpost".
  • @POST Indicates that the annotated method responds to HTTP POST requests. In the Jersey example, doPostMimeFormEncoded() served to process HTTP POST.

For a complete list of annotations defined in JAX-RS, refer to the Java API for JAX-RS documentation.

Apache-CXF

Currently, there are two ways to build RESTful services with CXF:

  1. JAX-RS APIs
  2. JAX-WS Provider and Dispatch APIs

A Simple JAX-RS Web Service with Apache-CXF

Download the source for the latest distribution of Apache CXF, which includes JAX-RS examples in the jax-rs directory under samples and a POM for Maven builds. Please review the README in the samples directory.

Follow the process outlined for Jersey in the previous section to build a Maven template in Eclipse (choose the Group Id and Artifact Id as listed in the POM of the sample distribution). After you have created the project, make sure the package structure reflects the one shown in the sample. Next, copy/extract the files from the distribution into the Eclipse workspace, including the POM (replacing the existing POM in the Eclipse/Maven project).

The sample at C:\apacheSourceREST\apache-cxf-2.2.3-src\distribution\src\main\release\samples\jax_rs\basic shows how to build REST-based web services using JAX-RS. It has two parts: a server and a client.

On the server side:

  • The root resource class CustomerService.java demonstrates how to build a RESTful web service with the JAX-RS (JSR-311) APIs.
  • The main URI /customerservice/ is denoted by @Path at the class level. It responds to GET at the sub URI /customers/{id}/), PUT at /customers/, POST at /customers/, and DELETE at /customers/{id}/.
  • The method getOrder(@PathParam("orderId") String orderId) is an example of a sub-resource locator because it doesn't use a request method designator.
  • An HTTP GET request to URL http://localhost:9000/customerservice/customers/123 returns an XML document representing the customer 123. The annotation @XmlRootElement defines an XML element name for the XML schema type of the corresponding classes (Customer, Order, Product) using JAXB.

On the client side:

  • The sample demonstrates how to send HTTP GET/POST/PUT/DELETE requests using the Apache-specific org.apache.commons.httpclient.HttpClient.

Conclusion

REST is an architectural style that provides a simple and uniform way of calling server-side resources using HTTP web services. Developing web services has never been easy, but REST assists the developer with an inherent loose coupling of client and server without the complications of WSDL or XML. In this article, we have covered the basic definition of REST and demonstrated two frameworks that support REST concepts.

References

Jersey User Guide
Grizzly
JSR 311 JAX-RS specification
JAX-RS API
Jersey Client API
Apache CXF
Apache CXF API
Source Code

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date