简介:
实验多个过滤器进行拦截和放行时的运行顺序:
首先创建AServlet:
package demo1; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/AServlet") public class AServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("------Aervlet-----"); } }
然后创建两个过滤器:
AFilter:
package demoFilter; 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; public class AFilter implements Filter { /** * 创建之后立即执行,用来做初始化,Filter在服务器启动时就创建 */
public void init(FilterConfig filterConfig) throws ServletException { System.out.println("AFilter:过滤器出生!"); } /** * 每次过滤时都会执行 */
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("AFilter:拦截成功!"); chain.doFilter(request, response); System.out.println("AFilter:已放行!"); } /** * 销毁之前执行,用来对非内存资源进行释放 */
public void destroy() { System.out.println("AFilter:过滤器死亡!"); } }
BFilter:
package demoFilter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class BFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("BFilter:拦截成功!"); chain.doFilter(request, response); // 放行:让资源请求通过
System.out.println("BFilter:已放行!"); } }
然后在web.xml中配置Filter:
这里AFilter是拦截所有资源,BFilter只拦截AServlet;
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>day0412_1</display-name>
<filter>
<filter-name>AFilter</filter-name> <!-- 自定义名称 -->
<filter-class>demoFilter.AFilter</filter-class> <!-- Filter类所在路径 -->
</filter>
<filter-mapping>
<filter-name>AFilter</filter-name> <!-- 自定义名称匹配 -->
<url-pattern>/*</url-pattern> <!-- 拦截的资源路径 -->
</filter-mapping>
<filter>
<filter-name>BFilter</filter-name> <!-- 自定义名称 -->
<filter-class>demoFilter.BFilter</filter-class> <!-- Filter类所在路径 -->
</filter>
<filter-mapping>
<filter-name>BFilter</filter-name> <!-- 自定义名称匹配 -->
<url-pattern>/AServlet</url-pattern> <!-- 拦截的资源路径 -->
</filter-mapping>
</web-app>
再创建一个jsp资源文件:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="ISO-8859-1"%>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>my index.jsp</title>
</head>
<body>
<% System.out.println("This is a apple!!!!!"); %>
<h1>This is a JSP named index.jsp!!</h1>
</body>
</html>
启动服务器:
从浏览器进行访问AServlet:
查看控制台的输出内容:
在AFilter拦截后进行了放行,马上又遭到了BFilter的拦截,然后被BFilter放行后执行目标资源。
从前到后是:AFilter --> BFilter --> 目标资源
从后到前是:目标资源 --> BFilter --> AFilter
这样就能发现doFilter()会像一个堆栈一样以 先执行的后结束 的顺序进行执行。
然后是访问jsp文件:
控制台的输出结果:
结论:
- Filter的doFilter()方法在执行的时候:
-- 如果执行时存在下一个过滤器,则执行下一个过滤器
-- 如果没有则执行目标资源
-- 一直到执行完目标资源后又反向执行直到每一个Filter都执行结束
也就是说等后面的Filter执行完了才会结束前面的Filter。