JAX-RS 2.0 : Server side Processing Pipeline

The inspiration for this post was the Processing Pipeline section in the JAX-RS 2.0 specification doc (Appendix C). I like it because of the fact that it provides a nice snapshot of all the modules in JAX-RS – in the form of a ready to gulp capsule !

Blog_JAX-RS_Processing_Pipeline

Courtesy – JAX-RS 2.0 Specification Document

So I thought of using this diagram to provide a brief overview of the different JAX-RS components and how they orchestrate with each other.

What’s covered ?

  • Filters (Request and Response)
  • Method matching
  • Injection
  • Interceptors (Request and Response)
  • Entity Providers (Request and Response)

Note: what’s discussed here is the server side processing pipeline i.e. the sequence of actions which are triggered after the client sends an HTTP request (GET, POST, PUT etc)

It all begins when the client (browser or custom REST client) sends an HTTP request to your awesome RESTful service!

Request Filters (chain)

req-filters

The client request is handled by JAX-RS Filters. They are applicable on both the server and client side (we are going to look at server side filters – both request and response based)

  • Filters are optional components and you can write one by simply implementing the ContainerRequestFilter interface. They need to be annotated using @Provider annotation for automatic detection by the JAX-RS run time

  • One can mutate the instance of ContainerRequestContext and change attributes like headers, cookies, URI etc. Filters do not allow you to access the HTTP request body/message payload (that’s something which Interceptors can do)
  • Can be used to implement logging, authentication etc
  • If the filter implementation class needs to be executed before the resource method matching, use the @PreMatching annotation on the implementation class.
  • Filters can be bound to ALL JAX-RS methods (globally) or selectively by using @NamedBinding annotation or an implementation of the DynamicFeature interface
  • The @Priority annotation can be used to determine the order of execution of multiple filters – a sequential chain.

Method matching

After (successful) filter execution, the JAX-RS run time initiates the resource method matching process

  • The exact method to be invoked is based on the algorithm outlined by the specification (although JAX-RS providers are not bound by it)
  • It’s determined by a combination of below mentioned annotations
  • @GET, @PUT, @POST, @DELETE etc – these are the annotations which should match up to the actual HTTP operation (the mapping of the annotation to the HTTP verb is rather obvious)
  • @Path – its value (relative to the context root) is used to map the request URI e.g. /tweeters/all
  • @Consumes – its values should match the Content-Type header value sent in the HTTP request
  • @Produces – its values should match the Accept header value sent in the HTTP request

HTTP components injection

After the method matching is complete, the required HTTP components get injected into JAX-RS Resource classes (if configured) by the the JAX-RS run time. All we need to do is use the appropriate annotation

HTTP URI parameters

Other HTTP components

JAX-RS makes it easy to access (inject) HTTP request components like headers, cookies and even HTTP form data

  • @HeaderParam – extracts headers of a request. You can also use @Context annotation to inject an instance of HttpHeaders
  • @CookieParam – used to inject HTTP cookies from a HTTP request

  • @FormParam – can help inject values from attributes sent via a HTML Form using the HTTP POST request

  • @BeanParam – Can help use all the above injection related annotations on the instance variables of a custom domain class rather than using these to inject values into individual method parameters

Request Interceptors (chain)

req-interceptors-entityproviders

Interceptors are applicable on both the server and client side (we are going to look at server side interceptors only – both request and response based)

  • Interceptors help allow mutation of the HTTP request payload before it is processed
  • Request Interceptors are invoked only when a MessageBodyReader (see next topic) implementation is registered with the JAX-RS run time.
  • Interceptors for incoming server requests are handled by implementations of the ReaderInterceptor interface and need to be annotated using @Provider annotation for automatic detection by the JAX-RS run time

  • The ReaderInterceptorContext instance is passed by the JAX-RS run time and it has access to the HTTP body in the form of java.io.InputStream
  • Interceptors can be bound to ALL JAX-RS methods (globally) or selectively by using @NamedBinding annotation or an implementation of the DynamicFeature interface
  • Interceptors can be chained and prioritized (using @Priority) and calling the proceed method of the ReaderInterceptorContext automatically invokes the next interceptor in the chain or the MessageBodyReader implementation itself
  • A ReaderInterceptor acts as a wrapper around the MessageBodyReader (invokes it internally)

Entity Providers (converting HTTP request payload to Java type)

Entity Providers help in conversion of HTTP message payload to its appropriate Java type (for injection into the method parameters of JAX-RS resource classes) and vice versa

  • The conversion of HTTP request payload to its corresponding Java type is done by a concrete class implementing the MessageBodyReader interface
  • The readFrom method of the MessageBodyReader implementation is where the action takes place. The JAX-RS run time passes in all the contextual information including the payload itself (in the form of an InputStream) which can then be introspected and converted into the appropriate Java type.

  • JAX-RS spec mandates that an implementation should contain out-of-of-the-box implementations of MessageBodyReader interface for certain Java types like String, InputStream, File etc

Response Filter (chain)

resp-filters

Response Filters are similar to their Request-centric counterpart discussed previously.

  • Response Filters are optional components and you can write one by simply implementing the ContainerResponseFilter interface.
  • These type of filters are used to modify the response headers, add cookies etc. One can mutate the instance of ContainerResponseContext and change attributes like to achieve this. Filters do not allow you to access the HTTP response body/message payload (that’s something which Interceptors can do)
  • They need to be annotated using @Provider annotation for automatic detection by the JAX-RS run time

  • Filters can be bound to ALL JAX-RS methods (globally) or selectively by using @NamedBinding annotation or an implementation of the DynamicFeature interface
  • The @Priority annotation can be used to determine the order of execution of multiple filters – a sequential chain.

Response Interceptors (chain)

resp-interceptors-entityproviders

  • They are invoked only when a MessageBodyWriter (see next topic) is registered to handle outgoing HTTP payload
  • Interceptors for outgoing server responses are handled by implementations of the class WriterInterceptor and need to be annotated using @Provider annotation for automatic detection by the JAX-RS run time

  • Interceptors can be chained and prioritized (using @Priority) and calling the proceed method of the WriterInterceptorContext automatically invokes the next interceptor in the chain or the MessageBodyWriter implementation itself
  • A WriterInterceptor acts as a wrapper around the MessageBodyWriter (invokes it internally)

Entity Providers (converting Java object to HTTP response payload)

  • The conversion of a Java object returned by the application code to HTTP response payload is done by a concrete class implementing the MessageBodyWriter interface
  • The writeTo method of the MessageBodyWriter implementation is where the action takes place. The JAX-RS run time passes in all the contextual information along with the OutputStream to which the which the response stream can be written to after conversion from its Java type

  • JAX-RS spec mandates that an implementation should contain out-of-of-the-box implementations of MessageBodyWriter interface for certain Java types like String, InputStream, File etc

Alright then ! This was a rather brief overview of how server side request processing works in JAX-RS and which components come into play.

Thanks for reading. Cheers !

References

About Abhishek

Currently working as a Senior Product Manager in the Oracle Cloud Application Development team with a focus on Oracle Cloud PaaS portfolio. When not hovering in the clouds, I stay grounded with Java EE
This entry was posted in Java, Java EE and tagged , , , . Bookmark the permalink.

9 Responses to JAX-RS 2.0 : Server side Processing Pipeline

  1. What is difference between JAX-RS filter and interceptors? says:

    Can you explain when to use filter and when to go for interceptors while writing JAX-RS service?
    or What is difference between JAX-RS filter and interceptors?

    Like

    • Abhishek says:

      Filters are suitable for use cases where you would want to access/modify/work with request parameters such as the HTTP headers, cookies etc. For more details, you should check the ContainerRequestContext and ContainerResponseContext classes to see what they offer.

      Interceptors should be used to work with the HTTP payload itself e.g. a JSON payload submitted via a POST request. Please be informed that an Interceptors are closely tied to MessageBosyReader and MessageBodyWriter i.e. they are invoked by the JAX-RS runtime only when these are required to marshal/unmarshal b/w payload and Java representations. I would suggest looking at the WriterInterceptorContext and the ReaderInterceptorContext class for further clarity

      Hope that helped and thanks for reading !

      Like

  2. Shola says:

    Best resource YET on how Filters and Interceptors work on JAX-RS! Thanks for this! Helped me a lot!

    Like

  3. Andy says:

    Perfekt introduction: short but very clear.
    Thanks a lot to explain this pipelin.

    Like

  4. Pingback: Sharing data between JAX-RS filters | Thinking in Java EE (at least trying to!)

  5. Pingback: Sharing Data Between JAX-RS filters | Voxxed

  6. Gaurav Khanna says:

    Thanks for the write-up.
    Question:
    Are the response filters guaranteed to be invoked even if there is an exception up in the chain?

    Thanks.

    Like

    • Abhishek says:

      Yes. The response filters get invoked irrespective of whether or not the request filters get aborted.
      Thanks for reading and apologies for the (extremely) delayed response

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s