过滤器Filter详解

365bet体育手机 📅 2025-08-19 16:42:01 👤 admin 👁️ 8947 ❤️ 25
过滤器Filter详解

在 Java Web 开发中,你是否遇到过这样的需求:

✅ 用户必须登录才能访问订单页面✅ 所有请求统一设置 UTF-8 编码避免乱码✅ 记录每个请求的访问日志用于审计✅ 防止跨站脚本攻击(XSS)✅ 响应数据压缩以提升性能这些看似分散的功能,其实都可以通过一个强大的机制统一实现:Filter(过滤器)。

🔐 Filter 就像网站的“保安”或“安检门”,它在请求到达业务逻辑之前、响应返回客户端之前,进行拦截、检查、处理,是构建安全、高效 Web 应用的基石。

一、什么是 Filter?Filter 是 Java Servlet 规范中定义的一个接口(javax.servlet.Filter),用于对进入 Web 应用的 请求(Request) 和 响应(Response) 进行预处理和后处理。

核心能力:✅ 拦截所有匹配路径的 HTTP 请求✅ 在请求到达 Servlet 之前进行处理(如:登录校验、编码设置)✅ 在响应返回客户端之前进行处理(如:压缩、添加头信息)✅ 可以放行请求,也可以直接拦截并返回响应(如:跳转登录页)二、Filter 的核心作用作用

典型场景

权限控制

登录校验、角色权限验证

编码处理

统一设置请求/响应字符编码(UTF-8)

日志记录

记录请求路径、IP、耗时等

安全防护

XSS 过滤、CSRF 防护、IP 黑名单

性能优化

响应压缩(GZIP)、缓存控制

请求改造

修改请求头、包装 Request

响应改造

修改响应头、包装 Response

三、Filter 的生命周期(由 Servlet 容器管理)Filter 的生命周期由 Web 容器(如 Tomcat)控制,分为四个阶段:

阶段

方法

调用时机

调用次数

实例化

构造函数

容器启动时

1 次

初始化

init(FilterConfig config)

实例化后

1 次

过滤处理

doFilter(ServletRequest, ServletResponse, FilterChain)

每次请求匹配时

N 次

销毁

destroy()

容器关闭时

1 次

💡 类比:就像保安的上班流程:打卡(构造)→ 接收任务(init)→ 检查人员(doFilter)→ 下班(destroy)

四、Filter 核心接口详解1. javax.servlet.Filter所有过滤器必须实现的接口,定义三个核心方法:

代码语言:java复制public interface Filter {

void init(FilterConfig config) throws ServletException;

void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;

void destroy();

}2. FilterChain:过滤器链多个 Filter 按顺序组成一条“过滤链”chain.doFilter(request, response) 是放行请求的关键调用后,请求进入下一个 Filter 或目标资源不调用,则请求被拦截3. FilterConfig提供 Filter 的配置信息可获取初始化参数(init-param)可获取 Filter 名称、ServletContext 等五、如何实现一个 Filter?步骤 1:创建 Filter 类代码语言:java复制import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

public class MyFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

// 初始化:读取配置参数

String encoding = filterConfig.getInitParameter("encoding");

System.out.println("Filter 初始化,编码:" + encoding);

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

System.out.println("👉 请求拦截: " + req.getRequestURI());

// ✅ 预处理:例如设置编码

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

// 🔁 放行请求(关键!)

chain.doFilter(request, response);

// ✅ 后处理:例如记录响应

System.out.println("👈 响应完成: " + response.getContentType());

}

@Override

public void destroy() {

System.out.println("🔒 Filter 销毁,释放资源");

}

}六、Filter 的配置方式方式 1:web.xml 配置(传统方式)代码语言:xml复制

myFilter

com.example.MyFilter

encoding

UTF-8

myFilter

/*

方式 2:@WebFilter 注解(Servlet 3.0+)代码语言:java复制import javax.servlet.annotation.WebFilter;

import javax.servlet.annotation.WebInitParam;

@WebFilter(

filterName = "myFilter",

urlPatterns = {"/api/*", "/user/*"},

initParams = {

@WebInitParam(name = "encoding", value = "UTF-8")

}

)

public class MyFilter implements Filter {

// ...

}方式 3:Spring Boot 中使用 @Component + @WebFilter代码语言:java复制import org.springframework.stereotype.Component;

import javax.servlet.annotation.WebFilter;

@Component

@WebFilter(urlPatterns = "/*", filterName = "logFilter")

public class LogFilter implements Filter {

// ...

}✅ Spring Boot 注意:需在启动类上添加 @ServletComponentScan

代码语言:java复制@SpringBootApplication

@ServletComponentScan // 启用 @WebFilter 扫描

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}七、Filter 拦截路径配置拦截模式

示例

说明

精确匹配

/login

只拦截 /login

目录匹配

/api/*

拦截 /api/ 下所有路径

后缀匹配

*.jsp

拦截所有 .jsp 文件

全部拦截

/*

拦截所有请求(慎用)

⚠️ 注意:多个路径可用数组配置:

java深色版本@WebFilter(urlPatterns = {"/api/*", "/user/*"})

八、Filter 执行流程(多 Filter 链)当多个 Filter 拦截同一请求时,形成 Filter Chain,执行顺序如下:

代码语言:javascript代码运行次数:0运行复制客户端请求

[Filter 1] → doFilter() → 预处理

[Filter 2] → doFilter() → 预处理

... 更多 Filter

[目标资源] → Servlet / Controller

[Filter 2] ← 后处理 ← doFilter() 返回

[Filter 1] ← 后处理 ← doFilter() 返回

响应返回客户端执行顺序规则:注解方式:按 类名的字母顺序 升序执行(如 AFilter → BFilter)web.xml 方式:按 的声明顺序执行💡 建议:使用 @Order 注解或 web.xml 明确控制顺序,避免依赖类名。

九、实战案例:登录校验 Filter需求:用户访问 /order/* 下的接口必须登录,否则跳转登录页。

实现:代码语言:java复制@Component

@WebFilter(urlPatterns = "/order/*", filterName = "authFilter")

public class AuthFilter implements Filter {

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

HttpServletResponse res = (HttpServletResponse) response;

// 获取会话中的用户

Object user = req.getSession().getAttribute("user");

if (user == null) {

// ❌ 未登录,拦截并跳转

System.out.println("🚫 未登录,跳转登录页");

res.sendRedirect("/login");

return; // 阻止继续执行

}

// ✅ 已登录,放行

System.out.println("✅ 用户已登录,放行请求");

chain.doFilter(request, response);

}

}流程图解:代码语言:javascript代码运行次数:0运行复制请求 /order/create

AuthFilter 检查 session

用户存在? → 是 → 放行 → OrderController

← 否 → 重定向 /login十、Filter vs Interceptor vs AOP特性

Filter

Interceptor

AOP

所属层级

Servlet 容器

Spring MVC

Spring AOP

拦截范围

所有 Web 请求(包括静态资源)

仅 Controller 请求

任意方法调用

依赖框架

Servlet API

Spring MVC

Spring AOP

执行时机

最早(进入 DispatcherServlet 前)

进入 Controller 前

方法调用前后

适用场景

编码、安全、日志

权限、日志、性能监控

事务、日志、缓存

✅ 推荐组合使用:

Filter:全局编码、安全过滤Interceptor:业务权限、接口日志AOP:事务管理、方法级监控十一、常见面试题1. chain.doFilter() 的作用是什么?是放行请求的关键。调用后,请求进入下一个 Filter 或目标资源。不调用则请求被拦截。

2. Filter 的 init() 和 destroy() 方法调用几次?各调用 1 次,由容器管理生命周期。

3. 多个 Filter 的执行顺序如何控制?注解方式:类名字母顺序web.xml:按 声明顺序推荐使用 @Order 或 web.xml 明确顺序4. Filter 能拦截静态资源吗?✅ 能!只要路径匹配,/css/*.js、/img/* 等都能拦截。

5. 如何在 Filter 中修改请求体?需要包装 ServletRequest,继承 HttpServletRequestWrapper,重写 getReader() 或 getInputStream()。

十二、总结关键点

说明

Filter 是 Web 安全的第一道防线

拦截非法请求,保护核心资源

生命周期由容器管理

init → doFilter × N → destroy

chain.doFilter() 是放行关键

不调用则请求终止

Spring Boot 中使用 @Component + @WebFilter

配合 @ServletComponentScan

多 Filter 按顺序执行

形成“责任链”模式

适合做全局性、非业务性处理

编码、日志、安全、压缩

结语Filter 是 Java Web 开发中不可或缺的组件,它让你能够在不修改业务代码的前提下,为整个应用添加横切关注点(Cross-Cutting Concerns)。

🔑 核心思想:关注点分离 —— 业务逻辑归业务,安全、日志、编码归 Filter。

掌握 Filter,你就能为你的 Web 应用装上一把坚固的“安全锁”,让系统更安全、更稳定、更易维护。

相关养生推荐

这是一篇有气味的科普:全世界最臭的10种动物
亚洲365bet比分

这是一篇有气味的科普:全世界最臭的10种动物

📅 07-02 👁️ 1473
哪些软件能一键给电脑软件升级
365bet体育手机

哪些软件能一键给电脑软件升级

📅 08-03 👁️ 9501
DNF智慧的引导在哪
bat365官方网站

DNF智慧的引导在哪

📅 08-05 👁️ 7301
2025年油汀十大品牌
bat365官方网站

2025年油汀十大品牌

📅 07-29 👁️ 9041