JAX-RS - Filter Binding

[Updated: Jul 17, 2017, Created: Jul 17, 2017]

JAX-RS Name binding specification allows to have certain filter(s) executed only for a specific resource method(s).

To achieve name binding, we need to define an annotation (say A), which should be meta-annotated with @NameBinding annotation. Then to bind filters and resource methods together, we need to use our annotation A at both places.

Let's see an example to understand name binding.

Example

Defining the NameBinding:

@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Logged {
}

Binding Resource and Filter

Our filter:

@Provider
@Logged
public class LogFilter implements ContainerRequestFilter, ContainerResponseFilter {

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

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

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

The JAX-RS resource:

@Path("/customers")
public class MyResource {

  @GET
  public String getAllCustomers() {
      System.out.println("in getAllCustomers()");
      return "dummy-response for all customers";
  }

  @Logged
  @GET
  @Path("{id}")
  public String getCustomerById(@PathParam("id") String id) {
      System.out.println("in getCustomerById()");
      return "dummy-response for customer " + id;
  }
}

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:

in getAllCustomers()

Server output:

-- req info --
Path: customers/2
host: [localhost:8080]
connection: [keep-alive]
accept-encoding: [gzip, deflate]
accept: [*/*]
user-agent: [HTTPie/0.9.9]
in getCustomerById()
-- res info --
Path: customers/2
Content-Type: [text/plain]

As seen in above two outputs, the LogFilter only got executed for the URI '/customers/1' (where we used @Logged).

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 Binding Filter and Resource Example Select All Download
  • filter-binding
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also