JSR-339

JAX-RS provides a standard annotation-driven API that helps developers build a RESTful web service and invoke it. The standard principles of REST, such as—identifying a resource via URI; defining a set of methods to access the resource; and allowing for multiple representation formats of a resource—can be easily marked in a POJO via annotations.

JAX-RS 2 adds a Client API that can be used to access web resources. The API provides support for standard HTTP verbs, custom media types by integration with entity providers, and dynamic invocation:

Author author = ClientBuilder .newClient() .target("http://localhost:8080/resources/authors") .path("{author}") .resolveTemplate("author", 1) .request .get(Author.class);

The Client API also permits retrieval of the response asynchronously by adding an async() method call before the method invocation.

Author author = ClientBuilder.newClient().target(…).async().get(Author.class);

JAX-RS enables the creation of server-side endpoints using annotations. To enable JAX-RS, create a class that extends Application and specify the root server endpoint URL using the @ApplicationPath annotation:

@ApplicationPath("/webapi") public class MyApplication extends Application { }

JAX-RS 2 introduces asynchronous endpoints that may be defined to suspend the client connection if the response is not readily available and later resume when it is. Here, an Executor is used to perform work in a separate thread:

@Path("authors") public class AuthorEndpoint { @GET public void getAll(@Suspended final AsyncResponse ar) { executor.submit(new Runnable() { public void run() { ar.resume(authorsDatabase.getAll()); } )); } }

A synchronous endpoint that uses @PathParam to identify a single book. Note that this endpoint’s @Path will be combined with the @ApplicationPath; this results in a complete endpoint path of “/webapi/books/{id}”:

@Path("books/{id}") public class BookEndpoint { @GET public Book get(@PathParam("id") final int bookId) { return booksDatabase.get(bookId); } }

Filters and Entity Interceptors are extension points that customize the request/response processing on the client and the server side. Filters are mainly used to modify or process incoming and outgoing request or response headers. A filter is defined by implementing ClientRequestFilter, ClientResponseFilter, ContainerRequestFilter, and/or ContainerResponseFilter.

public class HeaderLoggingFilter implements ClientRequestFilter, ClientResponseFilter { // from ClientRequestFilter public void filter(ClientRequestContext crc) throws IOException { for (Entry e : crc.getHeaders().entrySet()) { … = e.getKey(); … = e.getValue(); } } // from ClientResponseFilter public void filter(ClientRequestContext crc, ClientResponseContext crc1) throws IOException { ... } }

Entity Interceptors are mainly concerned with marshaling and unmarshaling of HTTP message bodies. An interceptor is defined by implementing ReaderInterceptor or WriterInterceptor, or both.

public class BodyLoggingFilter implements WriterInterceptor { public void aroundWriteTo(WriterInterceptorContext wic) { wic.setOutputStream(...); wic.proceed(); } }

JAX-RS 2 also enables declarative validation of resources using Bean Validation 1.1. In addition to validating any @PathParam or @QueryParam method parameters, validation constraints may also be placed on the JAX-RS resource class fields:

@Path("/names") public class Author { @NotNull @Size(min=5) private String firstName; ... }

Public API selection from javax.ws.rs package: