How does one intercept a request during the Jersey lifecycle?
I've used Jersey for the better part of a year now and have just s开发者_开发知识库tumbled 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.
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
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.
For the server part we use a Jersey Specific class to do something like this: ContainerResponseFilter
The signature is:
public ContainerResponse filter(ContainerRequest request, ContainerResponse response)
then you can do calls like:
Object entity = response.getEntity();
... your logic here ...
return response;
Can this be of some help ?..
Have you looked at the Jersey ClientFilter
class ?
We are currently using this to intercept and perform API versioing etc.. There is built in logging filters - so you can look at the code for them to get an idea of what to write.
The signature is:
public ClientResponse handle(final ClientRequest cr) throws ClientHandlerException...
So you can start by doing stuff like:
....
cr.getHeaders()
....
return getNext().handle(cr);
精彩评论