How does one intercept a request during the Jersey lifecycle?

35,476

Solution 1

I've found the answer.

First, create a class that implements ContainerRequestFilter. The interface specifies the following method, in which the filtering takes place. The ContainerRequest object contains information about the current request.

public ContainerRequest filter(ContainerRequest req);

After that, include the following XML in the servlet configuration in web.xml

<init-param>
  <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
  <param-value>path.to.filtering.class</param-value>
</init-param>

Sources:

http://jersey.576304.n2.nabble.com/ContainerRequestFilter-and-Resources-td4419975.html http://markmail.org/message/p7yxygz4wpakqno5

Solution 2

This thread is a bit old, but I was having a fit of a time intercepting both before and after the request. After a long search on the web, I finally figured this out:

<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>
<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>

and then this class:

public class LoggingFilter extends LoggingFilter implements ContainerRequestFilter {

    private static final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    public static boolean verboseLogging = false;

    @Override
    public ContainerRequest filter(ContainerRequest arg0) {
        startTime.set(System.currentTimeMillis());
        return arg0;
    }

    @Override
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
        System.out.println(System.currentTimeMillis() - startTime.get().longValue());
        StringBuilder sb = new StringBuilder();
        sb.append("User:").append((request.getUserPrincipal() == null ? "unknown" : request.getUserPrincipal().getName()));
        sb.append(" - Path:").append(request.getRequestUri().getPath());
        //...
    }

This intercepts the request at the beginning and the end so you can put in a timer or whatever.

This works for Jersey 1.17. Not sure about 2.x.

Share:
35,476
cww
Author by

cww

Updated on July 09, 2022

Comments

  • cww
    cww almost 2 years

    I've used Jersey for the better part of a year now and have just stumbled upon a problem to which I can't find the answer: how do you intercept (or hook into) the Jersey request lifecycle?

    Ideally, I'd be able to perform some custom filtering/validation/rejection between the time the container accepts the request from the network and the time my handler methods are called. Bonus points if there's an easy way to filter the interceptors by sub-path (e.g. have one interceptor for anything under /, another for anything under /user/, etc.).

    Thanks!

    Edit: To be a bit clearer, the general idea here is to be able to write some code that will be run for many API calls without having to explicitly call that code from each handler method. This would reduce extra code and eliminate the need to pass request contexts around.

    • Marc
      Marc over 13 years
      What kind of filtering, validation, rejection do you want? For example, you can create your own MessageBodyWriter/Reader to handle validation. Or you can set the @Context in the constructor for custom HTTP header parsing or URI parsing.
    • cww
      cww over 13 years
      Most applications of this feature would be related to security. For example, my (non-Jersey) web application will generate one-time-use nonces for certain AJAX calls (all under the same path) to Jersey. The interceptor would be responsible for checking the validity of this nonce.
    • Mat
      Mat over 11 years
      @Marc can you tell a bit more about the "Or you can set the @ Context in the constructor for custom HTTP header parsing or URI parsing" part please ?
  • cww
    cww over 13 years
    It looks like this works on the client-side only. Do you know if there's a similar filtering mechanism for the server?
  • tddmonkey
    tddmonkey about 13 years
    Thanks for adding your solution - it's useful for the rest of us
  • Shekhar
    Shekhar almost 10 years
    Is there any annotation for this?
  • Neeraj Jain
    Neeraj Jain over 8 years
    How to Reject Request with this ?
  • David Brossard
    David Brossard over 4 years
    @Override public ContainerResponse filter(...) is not valid in this type of class.