过滤器链
概念
过滤器链简单理解就是几个过滤器连接在一起。
如上图,就过滤器功能来说,能够成功请求资源就必须要通过所有过滤器的过滤,如果有一个过滤器没有放行就无法到达下一个过滤器或者请求资源。
过滤器链执行顺序的结论
-
注解方式: Filter字母顺序或数字顺序,如AFilter优先于BFilter,Filter1优先于Filter2等。
-
配置文件Web.xml: filter-mapping在前的先。
关于过滤器链的实验
实验目的
1.探究过滤链的执行过程,并模拟过滤失败的情况
2.验证注解和配置文件两种情况下filter的执行顺序
步骤
1.创建两个filter,取名Filter1,Filter2;创建一个Servlet,取名Servlet
2.代码如下
@WebFilter("/*")
public class Filter1 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter1过滤器");
System.out.println("Filter1放行");
chain.doFilter(req, resp);
System.out.println("Filter1执行结束");
}
public void init(FilterConfig config) throws ServletException {
}
}
@WebFilter("/*")
public class Filter2 implements Filter {
public void destroy() {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter2过滤器");
System.out.println("Filter2放行");
chain.doFilter(req, resp);
System.out.println("Filter2执行结束");
}
public void init(FilterConfig config) throws ServletException {
}
}
@WebServlet("/hello")
public class Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("进入servlet");
System.out.println("请求资源ing...");
System.out.println("返回资源");
}
3.启动服务器,访问/hello,得到运行结果
4.根据输出信息,可以判断过滤链的执行过程如下:
过滤链的执行过程(Filter1,Filter2都放行)
过滤失败的情况
Filter1不放行,Filter2放行
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter1过滤器");
System.out.println("Filter1不放行");
//chain.doFilter(req, resp);
System.out.println("Filter1执行结束");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter2过滤器");
System.out.println("Filter2放行");
chain.doFilter(req, resp);
System.out.println("Filter2执行结束");
}
运行结果
根据输出结果可知,若Filter1不放行,则不会再进入Filter2…,如下图
Filter1放行,Filter2不放行
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter1过滤器");
System.out.println("Filter1放行");
chain.doFilter(req, resp);
System.out.println("Filter1执行结束");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("进入Filter2过滤器");
System.out.println("Filter2不放行");
//chain.doFilter(req, resp);
System.out.println("Filter2执行结束");
}
根据输出结果可知,若Filter放行,Filter2不放行,则不会再进入Servlet,如下图
过滤链执行顺序验证
注解
由上面的实验可知,Filter1优先Filter2,将Filter2修改名字为AFilter,Filter1修改名字为BFilter,并且都放行。
输出结果如下:
原输出结果,Filter1优先Filter2.
实验结果:AFilter(Filter2)优先 BFilter(Filter1)
结论:
注解方式: Filter字母顺序或数字顺序,如AFilter优先于BFilter,Filter1优先于Filter2等。
配置文件Web.xml
1.将AFilter(原Filter2)改名字回Filter2,BFilter(原Filter1)改名字回Filter1。
2.删除二者的@WebFilter("/*")注解
3.在Web.xml对Filter1,Filter2进行配置
<!--Filter1名称和所在包-->
<filter>
<filter-name>Filter1</filter-name>
<filter-class>filter.Filter1</filter-class>
</filter>
<!--Filter1过滤路径-->
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Filter2名称和所在包-->
<filter>
<filter-name>Filter2</filter-name>
<filter-class>filter.Filter2</filter-class>
</filter>
<!--Filter2过滤路径-->
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
输出结果
Filter1的 filter-mapping 在Filter2前,Filter1优先Filter2.
为了验证文章开头的结论,做以下对比实验:
(1)将Filter2的 Filter标签放在最前
<!--Filter2名称和所在包-->
<filter>
<filter-name>Filter2</filter-name>
<filter-class>filter.Filter2</filter-class>
</filter>
<!--Filter1名称和所在包-->
<filter>
<filter-name>Filter1</filter-name>
<filter-class>filter.Filter1</filter-class>
</filter>
<!--Filter1过滤路径-->
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Filter2过滤路径-->
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
输出结果不变。
(2)将Filter2的 filter-mapping 标签放在Filter1的 filter-mapping标签前
<!--Filter1名称和所在包-->
<filter>
<filter-name>Filter1</filter-name>
<filter-class>filter.Filter1</filter-class>
</filter>
<!--Filter2名称和所在包-->
<filter>
<filter-name>Filter2</filter-name>
<filter-class>filter.Filter2</filter-class>
</filter>
<!--Filter2过滤路径-->
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Filter1过滤路径-->
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
输出结果:Filter2优先于Filter1,得证!
结论:
配置文件Web.xml: filter-mapping在前的先。