JAX-RS - Client Interceptors

[Updated: Aug 1, 2017, Created: Aug 1, 2017]

The client side interceptors are similar to server side interceptors. They can use @Priority. They cannot use name binding and scanning/discovering related annotations such as @Provider.

Like other providers, we have to register client side interceptors manually.

To implement client side interceptor, we need to implement WriterInterceptor and/or ReaderInterceptor, they are used for request and response respectively.

Let's see an example how to use interceptors on the client side.

Example

A JAX-RS resource

@Path("/")
public class MyResource {

  @POST
  @Path("{path:.*}")
  public String getResponse(@PathParam("path") String path, String entity) {
      System.out.println("-- In the resource method, getResponse() --");
      System.out.println("request message body: \n"+entity);
      return "dummy response from response method.";
  }
}

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Implementing client side Interceptor

public class MyClientInterceptor implements WriterInterceptor, ReaderInterceptor {

  @Override
  public void aroundWriteTo(WriterInterceptorContext context)
          throws IOException, WebApplicationException {
      System.out.println("-- in MyInterceptor#aroundWriteTo() --");
      OutputStream os = context.getOutputStream();
      String msg = " My output message added in client interceptor.";
      os.write(msg.getBytes());
      context.proceed();
  }

  @Override
  public Object aroundReadFrom(ReaderInterceptorContext context)
          throws IOException, WebApplicationException {
      System.out.println("-- in MyInterceptor#aroundReadFrom() --");

      InputStream is = context.getInputStream();
      String body = new Scanner(is, "UTF-8").useDelimiter("\\A").next();

      context.setInputStream(new ByteArrayInputStream(
              (body+" My appended message from interceptor.\n").getBytes()));
      Object result = context.proceed();
      return result;
  }

}

Registering the Interceptor and making request

public class MyClient {
  public static void main(String[] args) {
      Client client = ClientBuilder.newBuilder()
                                   .register(new MyClientInterceptor())
                                   .build();

      WebTarget target =
              client.target("http://localhost:8080/app");
      
      String response = target.request()
                              .post(Entity.text(" My test request body."), String.class);
      System.out.println("-- response --");
      System.out.println(response);
  }
}

Output

-- in MyInterceptor#aroundWriteTo() --
-- in MyInterceptor#aroundReadFrom() --
-- response --
dummy response from response method. My appended message from interceptor.

The above output is on the client side.

The output on the server console:

-- In the resource method, getResponse() --
request message body:
 My output message added in client interceptor. My test request body.

Execution Order On the Client

Following shows is overall order of filters and interceptors on the client side

Client Request InitiatedClient Request FiltersClient Writer Interceptors
Client MessageBodyWriterServerClient Response Filters
Client Reader InterceptorsClient MessageBodyReaderClient Receives the Response

Example Project

Dependencies and Technologies Used :

  • jersey-server 2.25.1: Jersey core server implementation.
  • jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
  • JDK 1.8
  • Maven 3.3.9

JAX-RS Client Interceptor Example Select All Download
  • client-side-interceptor-example
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also