Engineering Full Stack Apps with Java and JavaScript
Filters are pluggable classes that stand between the client and a target component (like a servlet or JSP), within a web application. We can do pre or post processing of request/response data while it is coming from client to a servlet or from the servlet back to a client. Before filters were introduced in Java EE, we had to use servlets with RequestDispatcher to achieve pre or post processing of request/response data. Filters add a lot of flexibility over servlet for such extra processing which is not directly involved in response creation. A filter is a regular class that implement javax.servlet.Filter interface.
Filters are pluggable by design as it can be added or removed through the deployment descriptor or using the @WebFilter annotation. Some of the uses of filters are logging the request or response, security check before accessing a resource, encryption, image compression, caching etc. Filters are designed to be pluggable and should not act as a target resource. They should not be responsible for creating the HTML code. Adding or removing filters should not affect any functionality.
With servlet specification 2.4, we can now include or forward filters using the RequestDispatcher mechanism. With servlet specification 2.4, we can also insert filters between two components within the application that communicate using the RequestDispatcher mechanism. This can be also done through the deployment descriptor or using the @WebFilter annotation.
We can create filter chains and can execute all the filters in the chain while request is coming from client to a servlet or response is going from the servlet back to a client. This allows us to have functionality per filter, and remove that functionality alone without affecting other functionalities. Ordering of filters in the chain can be specified in the deployment descriptor or using the @WebFilter annotation.
Filter Lifecycle
Loaded
Filter class is loaded by the class loader.
Instantiated
Filter class is instantiated using the no-argument constructor.
init(FilterConfig)
A filter is initialized passing an implementation of the FilterConfig which contains default configuration information.
doFilter(ServletRequest, ServletResponse, FilterChain)
this is filter’s service method. All requests and responses in the chain pass through this method.
You need to explicitly call FilterChain’s doFilter method for the request to proceed further to other filters or the target resource.
You may block the request by not calling the next filter in the chain and return a response to client directly from the filter (appropriate for error cases).
You may wrap the ServletRequest in a ServletRequestWrapper implementation or ServletResponse in a ServletResponseWrapper implementation, before calling the doFilter method.
destroy()
When a filter is completely removed from service.
Methods of FilterConfig interface are:
getFilterName()
getInitParameter(java.lang.String name) – filter’s init parameter.
getInitParameterNames() – filter’s init parameters.
getServletContext()
Only method of FilterChain is:
doFilter(ServletRequest request, ServletResponse response)
Calling this method by a filter causes the next filter in the chain to be invoked, or if the calling filter is the last filter in the chain, causes the resource at the end of the chain to be invoked.
This is a blocking call as rest of the code in the filter will not be executed until this method returns.
Usually request object is processed before calling doFilter and response object is processed after the doFilter call returns.
Not calling this method will block the request from proceeding. You may block the request by not calling the next filter in the chain and return a response to client directly from the filter (appropriate for error cases).
A filter implementation may look like:
@WebFilter("/TargetServlet")
public class FirstFilter implements Filter {
public FirstFilter() {
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// code before target servlet execution or further filters in the chain
chain.doFilter(request, response);
// code after target servlet execution or further filters in the chain
}
public void destroy() {
}
}