What is FilterChain?
FilterChain is an interface of the servlet API. Implementation of it, is provided by server vendors. It provides following method:
You may recall that the Filter interface also has doFilter() method. That method has three parameters one of which is a FilterChain object. The doFilter() method of the Filter interface is used by the server to give a chance to a filter to apply its pre and post processing to the request. The doFilter() method of the FilterChain interface is used by the server to control the flow of a request in which one or more filter participates. Now, you would be wondering what is the flow control and why an extra object is required for it?
What is the need of FilterChain?
To understand the need of the FilterChain, lets review the work flow of a filter i.e. the sequence in which operations are performed by a filter. When a filter is invoked, it performs pre processing, invokes the next component and finally when the next component completes it processing, it performs the post processing.
A filter may participate in multiple requests and in each requests there may be different number of and different type of components. A filter know what pre and post processing it need to do but it doesn’t know in which request it will participate. If a filter doesn’t know in which request it is participating then it will not know which component is next to it then how can it invoke the next component?
The answer is: A filter invokes the next component with the help of a FilterChain object. Through the configuration of web.xml, the server knows how many components participate in which order in the processing of a request. For each request in the processing of which one or more filter participates, the server creates a FilterChain object. This object is provided the references of the participating components in the order of their participation. It is used by the server to start the processing and by the filters in getting their next component invoked.
How does a FilterChain object help filters in invoking their next component?
Let there be a web application having F1 & F2 filters and S1 & S2 servlets. Let filter F1 be associated to both the servlets and filter F2 be associated only to S2 servlet. Let the request of servlets S1 & S2 has following order of components: F1–>S1 and F1–>F2–>S2.
Now you can see that filter F1 is participating in two requests. In the first request, next component to it, is a servet i.e. in this case it need to invoke service() method after pre processing. In the second request, next component to it, is a filter i.e. it need to invoke doFilter() method after pre processing.
Following diagram describes the role of a FilterChain object in the context of the request of servlet S2 of the above example.
Description of the diagram:
1.0 – A client sends a request for the servlet S2.
1.1 – A FilterChain object is created by the sever and references of F1, F2 filters and S2 servlet are provided to it in the order or their participation.
1.2 – Processing is started by the server by invoking doFilter(request,response) method of the FilterChain.
1.3 – The FilterChain object, obtains the next element from the component’s list and checks its type. It is a filter hence the FilterChain object invokes is doFilter(request,response,chain) method. In this method, the FilterChain object provides its own reference to the filter as third argument. By giving its own reference to the filter, the FilterChain object is saying to the filter, do whatever pre processing you need to do and when you are done let me know, I will invoke the next component for you because I know who is next to you in the current request.
1.4 – After pre processing filter F1 asks the FilterChain object to invoke the next component by invoking its doFilter(request,response) method. It is the second invocation of the FilterChain’s method i.e. recursion is started.
1.5 – The FilterChain object again, obtains the next element from the component’s list and checks its type. It is also a filter hence its doFilter(request,response,chain) method is invoked as before.
1.6 – After pre processing filter F2 asks the FilterChain object to invoke the next component by invoking its doFilter(request,response) method. It is the third invocation of the method.
1.7 – The FilterChain object again, obtains the next element from the component’s list and checks its type. This time it is a servlet hence its service(request,response) method is invoked by the FilterChain.
1.8 – Request is processed by the servlet S2 and control is returned to the FilterChain object.
1.9 – The servlet S2 was invoked by the FilterChain because the filter F2 asked it to do so in the step 1.6 by invoking doFilter(request,response) method. Execution of the servlet S2, completes this method call hence control is returned to the Filter F2 by the FilterChain. To understand this step refresh following concepts related to method calls:
2.0 – Filter F2 applies post processing if any and returns the control the the FilterChain.
2.1 – Completion of post processing of filter F2 completes the second invocation of doFilter(request,response) method of FilterChain hence control is returned to the Filter F1 for post processing.
2.2 – Filter F1 applies post processing if any and returns the control the the FilterChain.
2.3 – Completion of post processing of filter F1 completes the first invocation of doFilter(request,response) method of FilterChain hence control is returned to the server.
2.4 – Response generated by the servlet S2 and filters F1 & F2 is returned to the client by the server.
If you have now understood the role of FilterChain then try to visualize yourself how the request of S1 servlet of the above example will be processed.