Servlet vs Filter
Use a Filter
when you want to filter and/or modify requests based on specific conditions. Use a Servlet
when you want to control, preprocess and/or postprocess requests.
The Java EE tutorial mentions the following about filters:
A filter is an object that can transform the header and content (or both) of a request or response. Filters differ from web components in that filters usually do not themselves create a response. Instead, a filter provides functionality that can be “attached” to any kind of web resource. Consequently, a filter should not have any dependencies on a web resource for which it is acting as a filter; this way it can be composed with more than one type of web resource.
The main tasks that a filter can perform are as follows:
- Query the request and act accordingly.
- Block the request-and-response pair from passing any further.
- Modify the request headers and data. You do this by providing a customized version of the request.
- Modify the response headers and data. You do this by providing a customized version of the response.
- Interact with external resources.
For authorization, a Filter
is the best suited. Here's a basic kickoff example of how a filter checks requests for the logged-in user:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
// User is not logged in. Redirect to login page.
((HttpServletResponse) response).sendRedirect("login");
} else {
// User is logged in. Just continue with request.
chain.doFilter(request, response);
}
}
Difference between servlet/servlet-mapping and filter/filter-mapping?
Servlet filters implement intercepting filter pattern. While servlet is the ultimate target of web request, each request goes through a series of filters. Every filter can modify the request before passing it further or response after receiving it back from the servlet. It can even abstain from passing the request further and handle it completely just like servlet (not uncommon). For instance caching filter can return result without calling the actual servlet.
What is the difference between a Servlet filter and a Jersey filter?
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.
What are the real time usage of Filter concept in Java Servlet?
Filters help you to intercept the incoming request and response.
Request filters can:
perform security checks,
reformat request headers or bodies,
audit or log requests,
Response filters can:
compress the response stream,
append or alter the response stream,
create a different response altogether.
javax servlet filter vs jersey filter
Whatever you decide, you will be using a javax.servlet based Filter implementation, since it is the base interface for every Filter
you use in Java EE.
http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html
Now, Jersey comes with an implementation that adds some functionality (access to your ContainerRequestContext
or whatever you would need inside your Jersey application). Are you using Jersey already in your application? Then go for it, if not I would not bother (at least a priori and without further information) and just go for the most simple possible implementation of javax.servlet.Filter
and put it straight into my web.xml
Difference between Filter and Listener in Servlet (Java EE)
Servlet Filter is used for monitoring request and response from client to the servlet, or to modify the request and response, or to audit and log.
Servlet Listener is used for listening to events in a web containers, such as when you create a session, or place an attribute in an session or if you passivate and activate in another container, to subscribe to these events you can configure listener in web.xml
, for example HttpSessionListener
.
Why java servlet is not a filter?
Example of filter is GZIP Filter that compresses response. Some servlet generates output, and gzip filter just compresses it. Filters may be mapped to process output from multiple servlets, or just for any path, independently of how exactly servlets are mapped.
Another examples of filters:
- filter to remove whitespace from output
- filter to set caching headers
- filter to check if user can actually access given URL
In each case, filter has opportunity to alter request or response, but typically doesn't generate response on its own.
What is the difference between a Servlet Filter and a Servlet Context Listener?
A Filter
intercepts on HTTP requests matching its URL pattern and allows you to modify them. See also its javadoc:
A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.
Filters perform filtering in the
doFilter
method. EveryFilter
has access to aFilterConfig
object from which it can obtain its initialization parameters, and a reference to theServletContext
which it can use, for example, to load resources needed for filtering tasks.Filters are configured in the deployment descriptor of a web application.
Examples that have been identified for this design are:
- Authentication Filters
- Logging and Auditing Filters
- Image conversion Filters
- Data compression Filters
- Encryption Filters
- Tokenizing Filters
- Filters that trigger resource access events
- XSL/T filters
- Mime-type chain Filter
A ServletContextListener
intercepts on webapp's startup and shutdown and allows you to execute some code on startup and/or shutdown. See also its javadoc:
Interface for receiving notification events about
ServletContext
lifecycle changes.In order to receive these notification events, the implementation class must be either declared in the deployment descriptor of the web application, annotated with
WebListener
, or registered via one of theaddListener
methods defined onServletContext
.Implementations of this interface are invoked at their
contextInitialized(javax.servlet.ServletContextEvent)
method in the order in which they have been declared, and at theircontextDestroyed(javax.servlet.ServletContextEvent)
method in reverse order.
When to use the one or the other should now be obvious. Use a Filter
if you want to intercept on HTTP requests maching a specific URL pattern because you want to check/modify the HTTP request/response. Use a ServletContextListener
if you want to intercept on webapp's startup and/or shutdown.
Please know where to find the javadocs and how to interpret them. They contain all answers to this kind of trivial questions.
ServletModule.filter versus @WebFilter
As far as I can tell, what I'm looking for is impossible. In order to have a Filter declared without the @WebFilter attribute, you must have a web.xml like this:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Application</display-name>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
So all in all, you can either use @WebFilter attribute, or you must have a web.xml, there is no way to avoid both for more easily readable configuration.
Related Topics
How to Have the Code Pause for a Couple of Seconds in Android
How to Start a New Android Activity Using Class Name in a String
Multiple Commands Through Jsch Shell
Android and Getting a View with Id Cast as a String
Calculating the Angle Between a Line and the X-Axis
Multiple Dex Files Define Landroid/Support/Annotation/Animres
The Activity Must Be Exported or Contain an Intent-Filter
Is There on Install Event in Android
String-Date Conversion with Nanoseconds
Intellij Build Error Context Mismatch
How to Fix Install_Parse_Failed_Manifest_Malformed in My Android Application
Theme.Appcompat.Light.Darkactionbar - No Resource Found
Using Serviceloader on Android
Android Webview Always Returns Null for JavaScript Getelementbyid on Loadurl