Filters and interceptors

Filters provide extended functionality such as logging and authentication. Interceptors provide extended functions such as entity compression. In this section, we will discuss the support for filters at specific extension points in JAX-RS 2.0 implementation. The two types of filters are provided in JAX-RS 2.0: client filters and container filters. The client filters are on the client side and the container filters are on the container side. Interfaces corresponding to the client filters are included in the Client API and are javax.ws.rs.client.ClientRequestFilter and javax.ws.rs.client.ClientResponseFilter. Interfaces for the container filters, which are included in the Server API, are javax.ws.rs.container.ContainerRequestFilter and javax.ws.rs.container.ContainerResponseFilter. To be discovered by the JAX-RS runtime, filters implementing the interfaces must be annotated with the @Provider annotation. Create Java classes LoggingFilter (for the container filter example), and ClientFilter (for the client filter example), as shown in Project Explorer.

Filters and interceptors

Before we discuss the client and container filters, we need to discuss the junctions at which the filters intercept communication between the client and the server:

  1. The ClientRequestFilter intercepts communication before the client HTTP request is sent over to the server.
  2. The ContainerRequestFilter intercepts after the client is sent over to the server but before the JAX-RS resource method is invoked.
  3. The ContainerResponseFilter intercepts after the JAX-RS resource method is invoked but before the response is sent back to the client.
  4. The ClientResponseFilter is invoked after the server HTTP response is sent over to the client but before the response is unmarshalled.

The junctions of request/response interception are illustrated in the following diagram:

Filters and interceptors

Creating a client filter

First, we will discuss the client filters with an example. The ClientRequestFilter is run in the invocation pipeline before the HTTP request is delivered to the network. The ClientRequestFilter should be annotated by @Provider, which is the marker that is discovered by the JAX-RS runtime during the scanning phase. The ClientResponseFilter is run after the response is received from the server and before the control is returned to the application. Make the ClientFilter class implement the ClientRequestFilter and ClientResponseFilter interfaces. Add implementation for the filter(ClientRequestContext arg0) and filter(ClientRequestContext arg0, ClientResponseContext arg1) methods. In the ClientRequestFilter implementation method filter(ClientRequestContext arg0), output some headers using the getHeaderString(String) method of ClientRequestContext. For example, the Accept-Charset and Accept-Encoding headers give out the following output:

System.out.println("Accept-Charset: " + arg0.getHeaderString("Accept-Charset"));
System.out.println("Accept-Encoding: " + arg0.getHeaderString("Accept-Encoding"));

Set a new resource URI using the setUri(URI) method as follows:

arg0.setUri(new URI("http://localhost:8080/jboss-resteasy/rest/helloworld/text/Smith,John"));

The ClientFilter class is listed as follows:

package org.jboss.resteasy.rest;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

@Provider
public class ClientFilter implements ClientRequestFilter, ClientResponseFilter {
  
  @Override
  public void filter(ClientRequestContext arg0, ClientResponseContext arg1)
  throws IOException {
  }
  @Override
  public void filter(ClientRequestContext arg0) throws IOException {
    
    System.out.println("Entity Class: " + arg0.getEntityClass());
    System.out.println("Accept: " + arg0.getHeaderString("Accept"));
    System.out.println("Accept-Charset: "
    + arg0.getHeaderString("Accept-Charset"));
    System.out.println("Accept-Encoding: "
    + arg0.getHeaderString("Accept-Encoding"));
    System.out.println("Accept-Language: "
    + arg0.getHeaderString("Accept-Language"));
    System.out.println("Accept-Ranges: "
    + arg0.getHeaderString("Accept-Ranges"));
    System.out.println("Allow: " + arg0.getHeaderString("Allow"));
    System.out.println("Authorization: "
    + arg0.getHeaderString("Authorization"));
    System.out.println("Cache-Control: "
    + arg0.getHeaderString("Cache-Control"));
    System.out.println("Content-Encoding: "
    + arg0.getHeaderString("Content-Encoding"));
    System.out.println("Content-Location: "
    + arg0.getHeaderString("Content-Location"));
    System.out.println("Accept-Encoding: "
    + arg0.getHeaderString("Accept-Encoding"));
    System.out.println("Content-Type: "
    + arg0.getHeaderString("Content-Type"));
    System.out.println("Host: " + arg0.getHeaderString("Host"));
    System.out.println("Pragma: " + arg0.getHeaderString("Pragma"));
    System.out.println("Server: " + arg0.getHeaderString("Server"));
    System.out.println("User-Agent: " + arg0.getHeaderString("User-Agent"));
    
    try {
      arg0.setUri(new URI(
      "http://localhost:8080/jboss-resteasy/rest/helloworld/text/Smith,John"));
    } catch (URISyntaxException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    //arg0.abortWith(Response.notAcceptable(null).build());
  }
}

For a client filter issue that could occur, refer to the section Fixing a Common Issue at the end of this chapter. In the client class, RESTEasyClient registers the client filter with the client:

client.register(ClientFilter.class);

We will use the following root resource class HelloWorldResource to test the client filter:

package org.jboss.resteasy.rest;
import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/helloworld")
public class HelloWorldResource {

  @GET
  @Produces("text/plain")
  @Path("/text/{name}")
  public String getClichedMessage(@PathParam("name") String name) {
    return "Hello " +name;
  }
}

The client class RESTEasyClient to test the client filter with is listed as follows:

package org.jboss.resteasy.rest;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.*;

public class RESTEasyClient {

  public static void main(String[] args) {
    Client client = ClientBuilder.newClient();
    client.register(ClientFilter.class);
    String response = client.target("http://localhost:8080/jboss-resteasy/rest/helloworld/text/John Smith").request("text/plain").get(String.class);
    System.out.println("Text response "+ response);
  }
}

Redeploy the jboss-resteasy application. To redeploy, right-click on pom.xml in Project Explorer and select Run As | Maven clean, and subsequently, right-click on pom.xml and select Run As | Maven install. Run the RESTEasyClient.java class to generate the following output in the Console screen shown as follows:

Creating a client filter

As we modified the resource URI in the client filter, the response message is not for John Smith as specified in the client class, but for Smith, John.

The filter chain processing may be aborted and response is returned to the client with the abortWith(Response response) method. The client response filters get applied before the client gets the response. As an example, break the filter chain and return a notAcceptable(null) response:

arg0.abortWith(Response.notAcceptable(null).build());

Keep RESTEasyClient and HelloWorldResource the same and redeploy the jboss-restaesy application. Rerun the RESTEasyClient class to generate the following output, which includes a NotAcceptableException shown as follows:

Creating a client filter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.47.144