详细分析Java中FilterChain过滤器的基本知识

前言

基本的Java知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

从实战中学习:

在这里插入图片描述

常用在一些重复代码,需要进行过滤的

在这里插入图片描述

1. 基本知识

FilterChain 是 Java 中 Servlet 过滤器机制的重要组成部分,定义了过滤器链的执行顺序和执行逻辑

FilterChain 主要用于控制多个过滤器的依次执行,直到所有过滤器都完成后再交由最终的目标资源(如 Servlet 或 JSP)处理请求

执行流程:

  1. 过滤器的定义和顺序:多个过滤器会在 web.xml 文件中配置,或者在代码中使用注解(如 @WebFilter)声明
  2. 过滤器链的构建:容器会根据配置或注解扫描到的过滤器,按顺序构建一个过滤器链(FilterChain)
  3. 执行顺序:请求到达后,第一个过滤器执行后调用 FilterChain.doFilter() 方法,传递请求到下一个过滤器,依次进行
  4. 最终资源处理:当过滤器链上的最后一个过滤器执行完毕后,调用目标资源(如 Servlet),开始响应流程
  5. 响应的返回:执行完目标资源后,响应会沿着过滤器链的反方向依次返回,使每个过滤器有机会处理响应

基本的工作原理如下:

核心方法是 doFilter(ServletRequest request, ServletResponse response),用于将请求和响应传递到过滤器链的下一个过滤器或目标资源

  • doFilter 方法:每个过滤器在其 doFilter 方法中调用 chain.doFilter(request, response),会将请求传递到下一个过滤器或目标资源
  • 处理请求和响应:过滤器可以在调用 chain.doFilter() 前后执行逻辑,从而对请求和响应进行处理
    例如,日志记录、权限校验、编码设置等

2. Demo

一个简单的 FilterChain 示例,展示了两个过滤器(LoggingFilter 和 AuthenticationFilter)如何在 FilterChain 中按顺序工作

1.定义第一个过滤器:LoggingFilter

package FilterChain知识;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Component
@WebFilter(urlPatterns = "/demo/*")
public class LoggingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("LoggingFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("LoggingFilter: 请求开始...");

        // 执行下一个过滤器或目标资源
        chain.doFilter(request, response);

        System.out.println("LoggingFilter: 响应返回...");
    }

    @Override
    public void destroy() {
        System.out.println("LoggingFilter 销毁");
    }
}

2.定义第二个过滤器:AuthenticationFilter

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Component
@WebFilter(urlPatterns = "/demo/*")
public class AuthenticationFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("AuthenticationFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        Cookie[] cookies = httpRequest.getCookies();
        System.out.println(cookies);
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println("Found cookie: " + cookie.getName() + "=" + cookie.getValue());
            }
        }

        // 继续执行过滤器链
        chain.doFilter(request, response);
    }


    @Override
    public void destroy() {
        System.out.println("AuthenticationFilter 销毁");
    }
}

3.定义目标资源:DemoServlet

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo/process")
public class DemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("DemoServlet: 处理请求...");
        resp.getWriter().write("Hello, FilterChain!");
    }
}

4.执行流程和结果
当访问 http://localhost:8080/demo/process 时,过滤器链将按顺序执行,以下是执行过程和输出顺序:

  1. LoggingFilter 开始处理请求
  2. AuthenticationFilter 进行身份验证
  3. DemoServlet 处理实际请求并生成响应
  4. 过滤器以相反顺序返回响应处理

大致的结果如下:

LoggingFilter 初始化
AuthenticationFilter 初始化
LoggingFilter: 请求开始...
AuthenticationFilter: 检查身份验证...
DemoServlet: 处理请求...
AuthenticationFilter: 响应返回后执行...
LoggingFilter: 响应返回...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值