How filter chain invocation works?
Each filter implements the javax.servlet.Filter
interface, which includes a doFilter()
method that takes as input a request
and response
pair along with a filter chain
, which is an instance of a class (provided by the servlet container) that implements the javax.servlet.FilterChain
interface. The filter chain reflects the order of the filters. The servlet container
, based on the configuration order in the web.xml
file, constructs the chain of filters
for any servlet
or other resource that has filters
mapped to it. For each filter in the chain, the filter chain object passed to it represents the remaining filters to be called, in order, followed by the target servlet.
If there are two filters
, for example, the key steps of this mechanism would be as follows:
1.The target servlet
is requested. The container
detects that there are two filters
and creates the filter chain
.
2.The first filter
in the chain is invoked by its doFilter()
method.
3.The first filter
completes any preprocessing, then calls the doFilter()
method of the filter chain
. This results in the second filter
being invoked by its doFilter()
method.
4.The second filter
completes any preprocessing, then calls the doFilter()
method of the filter chain
. This results in the target servlet
being invoked by its service()
method.
5.When the target servlet
is finished, the chain doFilter()
call in the second filter
returns, and the second filter
can do any postprocessing.
6.When the second filter
is finished, the chain doFilter()
call in the first filter
returns, and the first filter
can do any postprocessing.
7.When the first filter
is finished, execution is complete.
Filters can be interposed between servlets and the servlet container to wrap and preprocess requests or to wrap and postprocess responses. None of the filters are aware of their order. Ordering is handled entirely through the filter chain, according to the order in which filters are configured in web.xml
What is the purpose of javax.servlet.FilterChain?
My coworker (who's not registered on SO) explained that it's for applying global functionality to an app that you don't want to do in every single controller, such as checking if the user is logged in.
What is chain.doFilter doing in Filter.doFilter method?
Servlet Filters are an implementation of the Chain of responsibility design pattern.
All filters are chained (in the order of their definition in web.xml). The chain.doFilter()
is proceeding to the next element in the chain. The last element of the chain is the target resource/servlet.
servlet chain filter
The FilterChain#doFilter()
continues the request processing and only returns when the target controllers have finished their job and the response is been rendered and committed.
You should not invoke it if your intent is to change the request to a different server side destination by RequestDispatcher#forward()
(or when you want to let the client side send a new request by HttpServletResponse#sendRedirect()
). You should have noticed this by seeing IllegalStateException: response already committed
in the server logs.
So, either remove it so that you only end up with the forward,
request.getRequestDispatcher("/Translate").forward(request, response);
or make it a conditional
if (someCondition) {
chain.doFilter(request, response);
} else {
request.getRequestDispatcher("/Translate").forward(request, response);
}
Unrelated to the concrete question, if I understand/guess your actual functional requirement right, you're more looking for the RequestDispatcher#include()
in the /process
servlet. See also How do I execute multiple servlets in sequence?
Who will take the roll of service method in filters in java?
The doFilter() method is the one that is called whenever a Filter processes a request.
A simple example is as follows:
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// .. pre filter logic
chain.doFilter(request, response);
// .. post filter logic
}
The filter allows you to decide whether to continue processing the request i.e. whether subsequent filters will process this request and finally the servlet at the end. You can choose not to call chain.doFilter (good example of this would be if you're using the filter for authentication). See this guide for more information.
filterChain.doFilter is not moving to next filter
The doFilter()
is called each time when a request/response is passed through the chain. The FilterChain.doFilter()
method invokes the next filter in the chain and calls resource at the end of the chain if the filter is the last filter in the chain.
This is just a normal method and after it's execution the control will come to the next line. That's the reason you're getting the log after the if
condition.
If you want to ignore the execution of the next filter for certain URIs, I recommend you use the else
block.
if (ignorePath(path)) {
chain.doFilter(request, response);
LOGGER.log(Level.INFO, "Called doFilter for this URI");
} else {
LOGGER.log(Level.INFO, "doFilter is not called for this URI");
}
Related Topics
Using Eclipse Java Compiler (Ecj) in Maven Builds
How to Determine If a Point Is Inside a 2D Convex Polygon
How to Use a Java8 Lambda to Sort a Stream in Reverse Order
"Not Allowed to Load Local Resource: File:///C:....Jpg" Java Ee Tomcat
How to Deserialize a List Using Gson or Another JSON Library in Java
Must Issue a Starttls Command First
In Which Language Are the Java Compiler and Jvm Written
String Array Initialization in Java
Environment Variable with Maven
How to Deal with the Urisyntaxexception
Differencebetween Canonical Name, Simple Name and Class Name in Java Class
JPA How to Make Composite Foreign Key Part of Composite Primary Key
What in the World Are Spring Beans
Maven. Lambda Expressions Are Not Supported in -Source 1.5
Differencebetween Lowagie and Itext