Issue
I read a lot of tutorials but I don't understand what the differences are between Servlet filters and Jersey filters. Can anyone explain the differences to me?
Solution
In a Servlet container, you have Servlets and you have Servlet Filters. Generally, the Servlets handle processing of the request, and the Servlet Filter handles pre an post processing of the request. So a request flow looks like
Request --> Filter --> Servlet --> Filter --> Response
The Jersey application is implemented as a Servlet1. So in the above flow, just replace "Servlet" with Jersey.
Request --> Filter --> Jersey-Servlet --> Filter --> Response
Jersey also has its own filters, namely ContainerRequestFilter
and ContainerResponseFilter
. They serve the same same purpose as the Servlet Filter, just in the context of a Jersey application; they are for pre-processing and post-processing. The below flow is inside of a Jersey request.
Req --> ContainerRequestFilter --> Resource --> ContainerResponseFilter --> Res
So these filters serve the same purpose, pre and post processing of the request. The major difference is the level in which they are connected. Servlet filters are tied at the servlet level, while Jersey filters are tied at the Jersey level.
So which one should you use?
Well it depends on when you want it called and what information you need access to. Take security for example. When thinking about securing your application, you might want your security gates as far from the data as possible. So you might implement your security using Servlet filters. But you need information that can only be obtained inside the Jersey application. Then you would need to use the Jersey filters; for example, you need to know which resource method is called. You could only get this information from the ResourceInfo
inside a Jersey filter
class MyResource {
@RolesAllowed("ADMIN")
public Response get() {}
}
class AuthorizationFilter implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext request) {
Method method = resourceInfo.getResourceMethod();
RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class);
}
}
You couldn't do the above in a Servlet filter. This information is only accessible from the context of a Jersey application. Maybe you might want to handle the authentication in a Servlet Filter, and after authentication, store the results in the HttpServletRequest
attributes. Then in the authorization, you could take care of it at the Jersey level, as shown above. You could inject the HttpServletRequest
into the Jersey filter, and get the attributes from there.
This is just an example. There are so many use cases. You just need to decide what would be the best for your application, as far as which filter type to implement. Most of the time you could get away with using a Jersey filter, but sometimes you need to filter to be called as early in the request as possible, in which case you might want to use the Servlet Filter. And in other cases, you need access to information that can only be obtained inside a Jersey application. For this, you should use a Jersey filter.
Footnotes
1. The Jersey application can also be configured to be run as a Servlet Filter instead of a Servlet. I believe they gave this option due to the fact that some Jersey features require some functionality that is only present in a Filter.
Answered By - Paul Samsotha
Answer Checked By - Terry (JavaFixing Volunteer)