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