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.
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.
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.es.ext.MessageBodyReaderare responsible for serializing and deserializing between stream and Java types.
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 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.
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.
- Create a simple Maven project in Eclipse (3.3.2) using the configuration below. Among other things, Maven creates a POM and the project
- 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.
- Create a package
com.mycompany.resourcesin 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.
- Implement a Java class (
DeployRestByExample.java) in the
myrestapppackage 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:
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:
- Implement a JUnit TestJersey.java using the Jersey Client API. Add it to the
myrestapppackage under src/test/java, as shown here.
- 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.
- 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.