Close

JAX-RS - Aborting request processing from Filter by using ContainerRequestContext.abortWith()

[Last Updated: Jul 21, 2017]

A resource request can be aborted (usually based on some conditions) from a filter.

The method ContainerRequestContext#abortWith() aborts the filter chain processing and returns the Response object as if produced by calling the resource method. The other filters which have the lower priorities, are also aborted on the same 'request chain'. All filters on the 'response chain' will work as usual but on the aborted Response object.

Let's see an example to understand how that works.

Example

Implementing Filter

@Priority(1)
@Provider
public class InvalidRequestFilter implements ContainerRequestFilter {

  @Override
  public void filter(ContainerRequestContext reqContext) throws IOException {
      Response responseForInvalidRequest = validateRequest(reqContext);
      if (responseForInvalidRequest != null) {
          reqContext.abortWith(responseForInvalidRequest);
      }
  }

  private Response validateRequest(ContainerRequestContext reqContext) {
      UriInfo uriInfo = reqContext.getUriInfo();
      String path = uriInfo.getPath();
      if (path.equals("orders/history")) {
          String msg = String.format("The feature is not yet supported: %s%n", path);
          CacheControl cc = new CacheControl();
          cc.setNoStore(true);
          Response response = Response.status(Response.Status.NOT_IMPLEMENTED)
                                      .cacheControl(cc)
                                      .entity(msg)
                                      .build();
          return response;
      }
      return null;
  }
}

A log filter with lower priority:

@Priority(2)
@Provider
public class LogFilter implements ContainerRequestFilter, ContainerResponseFilter {

  @Override
  public void filter(ContainerRequestContext reqContext) throws IOException {
      System.out.println("-- request info --");
      UriInfo uriInfo = reqContext.getUriInfo();
      log(uriInfo, reqContext.getHeaders());
  }

  @Override
  public void filter(ContainerRequestContext reqContext,
                     ContainerResponseContext resContext) throws IOException {
      System.out.println("-- response info --");
      UriInfo uriInfo = reqContext.getUriInfo();
      log(uriInfo, resContext.getHeaders());
  }

  private void log(UriInfo uriInfo, MultivaluedMap<String, ?> headers) {
      System.out.println("Path: " + uriInfo.getPath());
      System.out.println("HEADERS:");
      headers.entrySet().forEach(h -> System.out.println(h.getKey() + ": " + h.getValue()));
  }
}

A JAX-RS resource

@Path("/")
public class MyResource {

  @GET
  @Path("{path:.*}")
  public String getResponse(@PathParam("path") String path) {
      return "dummy-response for " + path;
  }
}

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

mvn tomcat7:run-war

Output

Using HTTPie to access the resource:

Server output:

-- request info --
Path: orders
HEADERS:
host: [localhost:8080]
connection: [keep-alive]
accept-encoding: [gzip, deflate]
accept: [*/*]
user-agent: [HTTPie/0.9.9]
-- response info --
Path: orders
HEADERS:
Content-Type: [text/plain]
-- response info --
Path: orders/history
HEADERS:
Cache-Control: [no-store, no-transform]
Content-Type: [text/plain]

As seen in the last output, the resource request was aborted as per the logic implemented by our filter. Also as seen on the server console, the log filter was not invoked during the 'request processing chain' (it would run after InvalidRequestFilter if not aborted), but it was invoked on the 'response processing chain'.

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 - Aborting Request From Filter Example Select All Download
  • filter-abort-with-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • InvalidRequestFilter.java

    See Also