Learn with our tutorials and training

developerWorks provides tutorials, articles and other
technical resources to help you grow your development skills
on a wide variety of topics and products. Learn about a specific
product or take a course and get certified. So, what do you want to learn
about?

Featured products

Featured destinations

Find a community and connect

Learn from the experts and share with other developers in one of our
dev centers. Ask questions and get answers with dW answers. Search for local events
in your area. All in developerWorks communities.

Create RESTful Web services with Java technology

JAX-RS (JSR-311) is a specification providing for RESTful services
capability in a Java EE environment. It promises to give you a viable
alternative to traditional, SOAP-based Web services.

In this article, learn about the major components of JAX-RS. An example
illustrates how an enterprise exposes employee contact information in a
RESTful manner using the facilities in JAX-RS.

Background

Developers have been creating RESTful services in their Java applications
for years with a variety of tools. With the simplicity of a REST
architecture, the main requirement—ability to receive an
HTTP message and headers—can be served by a simple Java Web
container.

Java servlets are commonly used to develop RESTful applications. There is
no prescriptive pattern for using servlets. Usually, the servlet will
accept the request and parse the HTTP request URI itself, looking to match
the request to a known resource. For REST services development, the simple
servlet model is extended in more formalized APIs. As APIs developed on
top of the servlet model, though, none of them were developed as a formal
standard.

With the growing adoption of REST as an architecture, the Java Community
Process (JCP) sought to include formal support for REST in the upcoming
Java Enterprise Edition 6 release. JSR-311 was created, and has produced
the JAX-RS 1.0 specification, providing a new annotation-based approach to
developing RESTful services. In contrast to the servlet model, JAX-RS
annotations let you focus on your resources and data objects. And, you no
longer have to develop the communication layer (via the servlet).

Java
resources

JAX-RS establishes a vernacular to describe resources as represented by
its programming model. There are five main items: root resources,
subresources, resource methods, subresource methods, and subresource
locators.

Root
resources

Root resources are Java classes annotated with the @Path
annotation. The @Path annotation provides a
value attribute that indicates the path at which the resource
is available. The value attribute may be literal characters,
variables, or variables plus a customized regular expression. Listing 1
shows an example.

Listing 1. JAX-RS root
resources

Subresources

Subresources are Java classes returned as the result of a subresource locator invocation. They are similar to root
resources, except they are not annotated with the @Path
annotation since their path is described on the subresource locator.
Subresources usually contain methods that are annotated with HTTP request
method designators to serve the request. If they do not contain such
annotated methods, they will further resolve the resource handling the
request by delegating to the appropriate subresource locator.

Listing 2. JAX-RS
subresources

Listing 2 above shows the subresource returned by the
ContactsResource.getContactDepartment method. In this
example, if an HTTP GET request were sent to the
/contact/{contactName}/department path, the
getDepartmentName resource method in the
Department subresource would handle the request.

Resource
methods

Resource methods are Java methods in a root resource or subresource that
are bound to HTTP methods. The binding is done with an annotation such as
the @GET annotation.

In the example in Listing 3, an HTTP GET request sent to the
/contacts path would be handled by the
getContacts() resource method.

Subresource
methods

Subresource methods are very similar to resource methods; the only
difference is that subresource methods are also annotated with an
@Path annotation that further qualifies the selection of the
method.

In Listing 4, an HTTP GET request sent to the /contacts/ids
path would be handled by the getContactIds() subresource
method.

Subresource
locators

Subresource locators are methods that further resolve the resource that
should handle a given request. They are like subresource methods in that
they have an @Path annotation, but they do not have an HTTP
request method designator, such as the @GET annotation.

In the example above, any HTTP request to the
/contact/{contactName}/department path would be handled by
the getContactDepartment subresource locator. The
{contactName} part means that any legal URL value could
follow the contact path part.

Annotations

This section takes a look at some of the prominent annotations and their
uses. For a complete list of the annotations provided by the JAX-RS
specification, see the JSR-311 link in the Related topics section.

@Path

The @Path annotation is used to describe the location of a
root resource, subresource method, or subresource. The value
attribute can contain literal characters, variables, and variables with
custom regular expressions. The example in Listing 6 shows the primary
uses of the @Path annotation.

The annotation on the ContactsResource class indicates that
all requests to the /contacts path will be handled by the
ContactsResource root resource. The @Path
annotation on the getByEmailAddress means that any request
sent to /contacts/{emailAddress}, where
emailAddress represents the regular expression
.+@.+\\.[a-z]+, will be handled by the
getByEmailAddress.

The @Path annotation on the getByLastName method
specifies that all requests sent to the /contacts/{lastName}
path, where lastName represents a valid URL part that does
not match the regular expression in getByEmailAddress, will
be handled by the getByLastName method.

@GET, @POST, @PUT,
@DELETE, @HEAD

@GET, @POST, @PUT, @DELETE, and @HEAD are the HTTP request method
designator annotations. You can use them to bind Java methods in a root
resource or subresource to HTTP request methods. HTTP GET requests are
mapped to methods annotated with @GET; HTTP POST requests are mapped to
methods annotated with @POST; and so on. Users may also define their own
custom HTTP request method designator annotations by using the
@HttpMethod annotation.

The declaration above defines the @CustomGET annotation. This
annotation will have the same semantic value as the @GET annotation and
can be used in its place.

@Consumes and
@Produces

The @Consumes annotation represents the MIME types that a
resource accepts. The @Produces annotation represents the
MIME types a resource returns. These annotations can be found on a
resource, resource method, subresource method, subresource locator, or
subresource.

For the getByEmailAddress and the addContactInfo
methods above, they both can handle text/xml and
application/json. The resource representation that is
accepted or returned will depend on HTTP request headers set by the
client. The @Consumes annotation is matched against the
Content-Type request header to determine if a method can
accept the content of a given request.

In Listing 9, the Content-Type header of
application/json, along with the POST to path
/contacts, means the addContactInfo method in
our ContactsResource class will be called to handle the
request.

Listing 9. Usage of Content-Type
header

Conversely, the @Produces annotation is matched against the
Accept request header to determine if a client can handle the
representation returned by a given method.

Listing 10. Usage of Accept
header

GET /contacts/johndoe@us.ibm.com HTTP/1.1
Accept: application/json

In Listing 10, the GET request to
/contacts/johndoe@us.ibm.com means the getByEmailAddress
method will be called and the return format will be
application/json, not text/xml.

Providers

JAX-RS providers are application components that allow for customization
of runtime behavior in three key areas: data binding, exception mapping,
and context resolution (for example, providing JAXBContext instances to
the runtime). Each JAX-RS provider class must be annotated with the
@Provider annotation. The example below discusses the data
binding providers MessageBodyWriter and
MessageBodyReader.

MessageBodyWriter

MessageBodyWriters are used by a JAX-RS runtime to serialize the
representation of a returned resource. JSR-311 compliant runtimes provide
native support for common types (java.lang.String, java.io.InputStream,
JAXB objects, and so on), but a user can provide his or her own
MessageBodyWriter to the JAX-RS runtime. For example, you can supply a
custom MessageBodyWriter to handle the custom
ContactInfo Java type, as shown below.

The ContactInfoWriter will be called by the JAX-RS runtime
prior to serialization of a returned resource representation. If the
isWriteable returns true, and the @Produces is
the closest match for the @Produces value of the resource
method, the writeTo method will be called. At this point, the
ContactInfoWriter is responsible for serializing the contents
of the ContactInfo instance to the underlying
OutputStream.

MessageBodyReader

MessageBodyReaders are the opposite of MessageBodyWriters. JAX-RS runtimes
natively support the same types for deserialization as they do for
serialization. A user can also supply his or her own MessageBodyReader
implementation. The primary function of a MessageBodyReader is to read
from a request InputStream and deserialize the incoming bytes
into a Java object expected by the resource method. A
MessageBodyReader for the ContactInfo type might
look like Listing 12.

Similar to the MessageBodyWriter isWriteable, the
isReadable method of the ContactInfoReader will
be called to determine if the MessageBodyReader can handle the input. If
the isReadable returns true, and the @Consumes
value is the most compatible with the @Consumes value of the
resource method, the ContactInfoReader will be chosen. When
the readFrom method is called, the result will be the
creation of a ContactInfo instance based on the request
InputStream content.

Configuration

Thus far we've explored JAX-RS resource classes and a subset of the
provider classes (MessageBodyReaders and MessageBodyWriters). Now, how are
these classes configured within a JAX-RS runtime? It's achieved through
the extension of the javax.ws.rs.core.Application class. This class
provides a set of classes, or a set of singleton object instances, that
include all of the root-level resources and providers (classes annotated
with @Provider) in a JAX-RS application. If you were to
extend the Application class for the example contact information
application, it would look similar to Listing 13.

The getClasses method provides the JAX-RS runtime with a list
of classes it should consider for metadata. Note that the
getSingletons method returns nothing. Generally, it's okay to
treat JAX-RS providers as singletons, but treating a JAX-RS resource as a
singleton will require greater care. Annotation-based injection often used
by JAX-RS resource classes may not be supported in the case of a singleton
instance. Therefore, use of a singleton instance for JAX-RS resources
should be avoided unless carefully planned.

Provided you're deploying your JAX-RS application within a servlet
container, there are two main ways to register your
javax.ws.rs.core.Application subclass with the JAX-RS runtime. This is
handled with the web.xml of the WAR file, as shown below.

In a servlet container that's considered non-JAX-RS aware, the Application
subclass name should be supplied as an init-param within the servlet
definition. The name of the init-param must be javax.ws.rs.Application.
The servlet-class will likely be the JAX-RS runtime system servlet. You
can either list each possible URL pattern, or use the /* wild
card registration as shown below.

In a servlet container that's considered JAX-RS aware, the Application
subclass name can be supplied as the value of the servlet-class element
within the servlet definition. You still have the option to list the URL
patterns individually or use the /* wild card
registration.

JAX-RS in action with
Apache Wink

The next step is to find a runtime that supports the capabilities available
in JAX-RS. The Apache Wink project provides a JAX-RS compliant runtime
with all of the features described above (see Related topics). Wink was started as a collaborative effort between
various vendors and members of the open source community. The goal of the
project is to provide the most flexible and lightweight runtime possible.

In addition to standard JAX-RS features, Wink also provides enhanced
support for JSON, Atom, and RSS serialization formats. JAX-RS itself does
not provide a client API, but Wink includes its own model for a client API
that is completely resource-centric.

To simplify development of your Wink-based services, download the Wink 1.0
libraries and include them as the default JAX-RS library in your Rational
Application Developer (RAD) 7.5.5 development environment (see Related topics). In this update, RAD added a JAX-RS
facet that you can configure to support validators and annotation
assistance. This new facet also simplifies configuration of the servlet by
automatically generating the necessary servlet entries and mappings.

Summary

Compared to the traditional servlet model, JAX-RS provides a viable,
easier, more pluggable alternative to implementing RESTful services in
Java. Using annotations lets you easily provide path locations for Java
resources and bind Java methods to HTTP request methods. A pluggable
data-binding architecture provides some native Java type support and
allows full customization of the serialization/deserialization process.
The extension of the javax.ws.rs.core. Application subclass, and the
corresponding listing in the web.xml, mean easy deployment with minimal
deployment descriptor configuration.

This article only touched upon some of the capabilities offered by JAX-RS.
Two other JAX-RS provider types, ContextResolvers and
ExceptionMappingProviders, give further control to
application components in terms of providing application context (for
example, JAXBContext instances) and mapping runtime exceptions to HTTP
responses. Annotations are defined that govern injection of method
parameters and class members, which provide valuable contextual
information to applications during runtime. All in all, JAX-RS promises to
be an easy, pluggable, and comprehensive API for developing Java-based
RESTful services.