簡介:
實驗多個過濾器進行攔截和放行時的運行順序:
首先創建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。