上一节讲了责任链设计模式的原理和应用场景,本节就来看一个实际应用案例。
我们要分析的就是Java Web项目中的Filter。
Servlet中的Filter的作用就是在浏览器请求实际执行到目标Servlet之前,做前置处理,并可以在目标Servlet将结果返回到浏览器之前,对返回结果进行处理。
首先基于maven新建一个web项目,我们以idea为例,新建web项目。
1、菜单 File–>New–>Project
2、选择Maven,选择“maven-archetype-webapp”
3、定义Manve项目的GroupId和ArtifactId
这样就生成了一个WEB项目,接下来我们新建两个Filter类,分别是FilterA和FilterB。
package com.itzhimei.study;
import java.io.IOException;
public class FilterA implements javax.servlet.Filter {
public void destroy() {
}
public void doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse resp, javax.servlet.FilterChain chain) throws javax.servlet.ServletException, IOException {
System.out.println("FilterA Start...");
chain.doFilter(req, resp);
System.out.println("FilterA End...");
}
public void init(javax.servlet.FilterConfig config) throws javax.servlet.ServletException {
}
}
package com.itzhimei.study;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "FilterB")
public class FilterB implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("FilterB Start...");
chain.doFilter(req, resp);
System.out.println("FilterB End...");
}
public void init(FilterConfig config) throws ServletException {
}
}
web.xml添加配置:
<!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>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>FilterA</filter-name>
<filter-class>com.itzhimei.study.FilterA</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterA</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>FilterB</filter-name>
<filter-class>com.itzhimei.study.FilterB</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterB</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
启动这个web服务,并访问首页:
localhost:8080/
输出结果:
FilterA Start...
FilterB Start...
业务Servlet
FilterB End...
FilterA End...
我们按照结果,可以大概倒推出来Filter的逻辑:配置的责任链会依次执行,Filter的执行是在真正的目标Servlet之前和之后执行的。效果如下图:
![](https://www.itzhimei.com/wp-content/uploads/2020/06/image-1-1024x343.png)
两个Filter和Servlet的执行,就像是又给链条,一个接一个的执行,浏览器请求到后端服务后,先执行FilterA的code代码,然后执行chain.doFilter()方法;然后执行FilterB的code代码,然后执行chain.doFilter()方法,将请求继续像后传递继续执行,直到业务Servlet执行完成返回,又会依次执行B的code,A的code,然后返回结果给浏览器。
我们对代码进行断点,可以看到,项目中定义的Filter都会存到filters中,当前项目中有3个filter,两个是我们定义的,一个是tomcat的。
![](https://www.itzhimei.com/wp-content/uploads/2020/06/image-1024x334.png)
每当调用chain.doFilter()的时候,都会从filters中取出下一个filter继续执行。
pos表示当前执行到那个filter,n表示一个有多少个filter。
好了,这节就到这里,动手来自己写一下吧。