Filter多過濾器執行順序


簡介:

實驗多個過濾器進行攔截和放行時的運行順序:

首先創建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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM