Featured image of post Web开发-Filter过滤器

Web开发-Filter过滤器

1527字

Filter过滤器学习笔记

一、Filter概述

1.1 什么是Filter

Filter(过滤器)是JavaWeb三大组件之一(Servlet、Filter、Listener),主要用于拦截请求并实现一些通用功能:

  • 拦截特性:所有对Web服务器资源的请求都必须先经过过滤器
  • 常见用途
    • ✅ 登录校验
    • ✅ 统一编码处理
    • ✅ 敏感字符过滤
    • ✅ 权限控制

1.2 工作原理图解

image.png

二、Filter快速入门

2.1 基础实现步骤

1. 定义过滤器类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@WebFilter(urlPatterns = "/*") // 拦截所有请求
public class DemoFilter implements Filter {
    
    // 初始化方法(服务器启动时调用一次)
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("过滤器初始化...");
    }

    // 核心过滤方法(每次请求都会调用)
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        System.out.println("拦截到请求...");
        
        // 关键放行操作!没有这行代码请求将被阻塞
        chain.doFilter(request, response); 
    }

    // 销毁方法(服务器关闭时调用一次)
    @Override
    public void destroy() {
        System.out.println("过滤器销毁...");
    }
}

2. 启用Servlet组件扫描

1
2
3
4
5
6
7
@ServletComponentScan // 必须添加!启用Servlet组件支持
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.2 注意事项

⚠️ 必须调用chain.doFilter():否则请求会被拦截,无法继续后续处理
⚠️ @ServletComponentScan注解:忘记添加会导致过滤器不生效

三、登录校验过滤器实战

3.1 设计思路

image.png

3.2 完整实现代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        // 1. 获取请求URL
        String url = request.getRequestURL().toString();
        log.info("请求URL: {}", url);

        // 2. 登录请求直接放行
        if(url.contains("login")) {
            chain.doFilter(request, response);
            return;
        }

        // 3. 获取Token
        String jwt = request.getHeader("token");

        // 4. Token为空处理
        if(!StringUtils.hasLength(jwt)) {
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            response.getWriter().write("未携带令牌!");
            return;
        }

        // 5. 验证Token有效性
        try {
            JwtUtils.parseJWT(jwt); // 解析验证
        } catch (Exception e) {
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            response.getWriter().write("无效令牌!");
            return;
        }

        // 6. 验证通过,放行
        chain.doFilter(request, response);
    }
}

3.3 测试场景

测试场景 预期结果
未登录访问受限资源 自动跳转登录页
登录后访问资源 正常响应
Token过期访问 返回401错误

四、Filter高级特性

4.1 完整执行流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public void doFilter(...) {
    // 1. 前置处理逻辑
    System.out.println("前置处理...");
    
    // 2. 关键放行操作
    chain.doFilter(request, response);
    
    // 3. 后置处理逻辑
    System.out.println("后置处理..."); 
}

执行顺序:
前置处理 -> 资源访问 -> 后置处理

4.2 拦截路径配置

配置方式 示例 说明
全部拦截 /* 拦截所有请求
路径拦截 /user/* 拦截/user下的所有请求
后缀拦截 *.jsp 拦截所有jsp页面
精确拦截 /login 只拦截/login请求

4.3 过滤器链

当存在多个过滤器时:

  1. 执行顺序:按照类名自然排序(如AbcFilter先于DemoFilter)
  2. 执行流程image.png

五、最佳实践建议

  1. 性能优化

    • init()方法中初始化耗时资源
    • 避免在doFilter()中进行复杂计算
  2. 异常处理

    1
    2
    3
    4
    5
    6
    
    try {
        chain.doFilter(request, response);
    } catch (Exception e) {
        // 统一异常处理
        response.sendError(500, "服务器错误");
    }
    
  3. 实用技巧

    • 使用@Order注解控制过滤器顺序(Spring环境下)
    • 通过FilterConfig获取初始化参数
  4. 常见问题

    • ❌ 忘记调用chain.doFilter()
    • ❌ 未添加@ServletComponentScan
    • ❌ 在过滤器中抛出未处理异常

通过本学习笔记,可以全面掌握Filter的核心概念和实际应用,特别是在登录校验等安全场景下的关键作用。建议结合实际项目进行练习,加深理解。

如对内容有异议,请联系关邮箱2285786274@qq.com修改