JAX-RS

Learn about Java APIs for RESTful web services.

JAX-RS 1.0

JAX-RS 1.0 (the Java API for RESTful Web Services) was defined in JSR-311¹⁶⁴. It has many implementations, including the following:

  • CXF: A merger between XFire and Celtix (an Open Source ESB, sponsored by IONA, and originally hosted at ObjectWeb).
  • Jersey : The JAX-RS Reference Implementation from Oracle.
  • RESTEasy : JBoss’s JAX-RS project.

JAX-RS defines a set of request method designators for the common HTTP methods: @GET, @POST, @PUT, @DELETE, and @HEAD.

When a resource class is instantiated, the values of fields and bean properties annotated with one of the following annotations are set according to the semantics of the annotation:

  • @MatrixParam: Extracts the value of a URI matrix parameter.
  • @QueryParam: Extracts the value of a URI query parameter.
  • @PathParam: Extracts the value of a URI template parameter.
  • @CookieParam: Extracts the value of a cookie.
  • @HeaderParam: Extracts the value of a header.
  • @Context: Injects an instance of a supported resource.

Gotcha’s

  • If a subclass or implementation method has any JAX-RS annotations, then all of the annotations on the superclass or interface method are ignored.
  • If you’re using Spring AOP on your web-service classes, this interferes with the ability of your JAX-RS library to get your annotations. Either all of your methods should be added to the interface or CGLIB proxies have to be explicitly enabled. Consult Spring AOP documentation for more details.

JAX-RS 2.0

JAX-RS 2.0 adds a lot of new features to the REST API and comes with Java EE 7. It adds a client API, asynchronous processing for client and server, filters and interceptors, and some HATEOS (Hypermedia as the Engine of Application State) features.

Client API

JAX-RS 2.0 adds a client API to the standard. You can use the ClientFactory to Client and then a WebTarget. For example:

// Default instance of client
Client client = ClientFactory.newClient();
// Create WebTarget instance base
WebTarget base = client.target("http://example.org/");
// Create new WebTarget instance hello and configure it
WebTarget hello = base.path("hello").path("{whom}");
hello.register(MyProvider.class);

Then, to execute on the Web Target, do the following:

Response res = hello.pathParam("whom", "world").request("...").get();
This would result in a GET request on the URL http://example.org/hello/world

Asynchronous Processing

Asynchronous Processing and Asynchronous REST API calls were added as a first-class feature to JAX-RS. This allows the REST client to issue multiple requests in parallel and the server to handle such requests.

  • Server API support
    • Offload I/O container threads
    • Suspendable client connection
    • Leverage Servlet 3.x async support (if available)
  • Client API Support: request().async().get( callback ).

Filters & interceptors

On the server-side, we have two different types of filters:

  • ContainerRequestFilter runs before your JAX-RS resource method is invoked.
  • ContainerResponseFilter runs after our resource method.

On the client side, we also have two types of filters: ClientRequestFilter and ClientResponseFilter. ClientRequestFilters run before our HTTP request is sent to the server. ClientResponseFilters run after a response is received, but before the response body is unmarshalled. Filters are useful for cross-cutting features, such as:

  • Logging
  • Security
  • Compression

While filters modify request or response headers, interceptors deal with message bodies. Interceptors are executed in the same call stack as their corresponding reader or writer. There are two interceptor interfaces:

ReaderInterceptorWriterInterceptor

For example, Interceptors can be used to add digital signatures or “gzip” message bodies. Sometimes we want a filter or interceptor to only run for a specific resource method. We can do this with a @NameBinding annotation. Annotate a custom annotation with @NameBinding, and then apply that custom annotation to your filter and resource method.

@NameBinding
public @interface MyFilterBinding {}

@MyFilterBinding
public class MyFilter implements ContainerRequestFilter {
   /* code... */
}

Then, in your RESTful Service:

@Path
public class RestfulService {

     @GET
     @MyFilterBinding
     public String get() { /* code... */ }

HATEOS

JAX-RS 2.0 adheres more closely with REST principles and includes features of HATEOS.

It includes the following:

  • ID’s and links
  • (RFC-5988 Web Linking) Link types: Structural and Transitional
  • Use @Produces to define what is returned:
@GET
@Produces("text/plain", "text/html")
public Widget getWidget();

Get hands-on with 1200+ tech skills courses.