1. Preface
Is the filter-filter technology newly added to servlet2.3? . Complete process: pre-process user requests, send the requests to the servlet for processing and generate a response, and then filter the server response for post-processing.
Filter represents a responsibility sharing mode. So how is it reflected?
2. Responsibility Chain Model
Before explaining this in detail, let's take a look at the definition of the responsibility chain model: Multiple objects have the opportunity to process requests, so as to avoid coupling between request senders and recipients. Connect the object to a chain and pass the request along the chain until an object processes it.
For the filter, the request is pre-processed by the filter before it is sent to a detailed web resource (such as JSP/servlet, the web resource must be processed by the filter before it is returned to the client. Just like the following figure
After multiple filters are created, the client sends a request, which is facing the filter chain. The role mode is reflected here. This request will be passed one by one on the filter chain for preprocessing. After processing, it will be passed to the next filter until the last one, and then sent to the web for the corresponding issue and processing. Its UML diagram (not a complete structure diagram, but a structure diagram that reflects the role model) is as follows:
A filter interface defines three methods: Init () (initialization method); destroy () (destruction method); dofilter () (core responsibility method ); two detailed classes implement the filter interface: concretefilter1 and concretefilter2;
A filterchain interface defines a method: dofilter (); a detailed implementation class concretefilterchain;
The basic function of filterchain is to find the next filter.
3. Detailed Implementation
The following is a simple implementation of the above structure chart. It helps us understand the role model embodied in filter.
Concretefilter1 class
Package COM. test. filter; import Java. io. ioexception; import javax. servlet. filter; import javax. servlet. filterchain; import javax. servlet. filterconfig; import javax. servlet. servletexception; import javax. servlet. servletrequest; import javax. servlet. servletresponse;/*** concretefilter1 class * @ author pf **/public class concretefilter1 implements filter {// Private string encoding; @ overridepublic void destroy () {system. out. println ("concretefilter1 () destroy () Run");} @ overridepublic void dofilter (servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {system. out. println ("---- concretefilter1 () chain. dofilter () before calling: Pre-processing user requests (requests) "); // continue to run // If a filter is next to the request, the JSP is started if no filter is available, always call the last chain. dofilter (request, response); system. out. println ("concretefilter1 () chain. dofilter () after calling: Server Response (response) after processing ");} @ overridepublic void Init (filterconfig) throws servletexception {// system. out. println ("START init"); // This. encoding = filterconfig. getinitparameter ("encoding"); // system. out. println ("init get encoding:" + encoding); system. out. println ("concretefilter1 () Init () method call ");}}
Concretefilter2 class
Package COM. test. filter; import Java. io. ioexception; import javax. servlet. filter; import javax. servlet. filterchain; import javax. servlet. filterconfig; import javax. servlet. servletexception; import javax. servlet. servletrequest; import javax. servlet. servletresponse;/*** handler uses filter to uniformly process character sets * @ author pf **/public class concretefilter2 implements filter {// Private string encoding; @ overridepublic void destroy () {system. out. println ("concretefilter2 () destroy () Run");} @ overridepublic void dofilter (servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {system. out. println ("concretefilter2 () chain. dofilter () before calling "); // request. setcharacterencoding (encoding. dofilter (request, response); system. out. println ("concretefilter2 () chain. dofilter () called ") ;}@ overridepublic void Init (filterconfig) throws servletexception {// system. out. println ("START init"); // This. encoding = filterconfig. getinitparameter ("encoding"); // system. out. println ("init get encoding:" + encoding); system. out. println ("concretefilter2 () Init () method call ");}}
Web. xml
<?xml version="1.0" encoding="UTF-8"?><web-app 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"><filter><filter-name>ConcreteFilter1</filter-name><filter-class>com.test.filter.ConcreteFilter1</filter-class></filter><filter-mapping><filter-name>ConcreteFilter1</filter-name><url-pattern>*.jsp</url-pattern></filter-mapping><filter><filter-name>ConcreteFilter2</filter-name><filter-class>com.test.filter.ConcreteFilter2</filter-class></filter><filter-mapping><filter-name>ConcreteFilter2</filter-name><url-pattern>*.jsp</url-pattern></filter-mapping></web-app>
After the server is started, I am using tomcat. The following information is displayed:
It indicates that our filter object will be created when server is started.
Just ask a page and check the console again.
Disable server: destroys the filter object created when server is disabled.
Let's take a look at the filter from the above running results. We have set two filters, respectively concretefilter1 and concretefilter2. run according to the order we configured in Web. xml. First Run concretefilter1 and then run concretefilter2.
However, note that they call the chain dofilter method in the opposite order. Therefore, we can see from this result that the Operation Sequence of the filter follows the principle of "back-to-first-out. The sent URLs are pre-processed according to the configured order, but the processed requests are indeed run in the Reverse filter order first.
The following is a sequence diagram of his call process:
3. Summary:
The result of the code above shows that the filter implements the responsibility chain mode very well. For any request, a filter chain can process it, in fact, we don't know which one to process in detail, but we have already handled it for us before arriving at the servlet, so we can achieve very good decoupling and between objects.
Filter reflects the responsibility chain mode