技术Java过滤器和拦截器
penjcJava 过滤器与拦截器详解
在 Java Web 开发中,过滤器和拦截器是两种常用的机制,分别用于对 HTTP 请求和响应进行处理。它们虽然有些相似,但用途和实现方式存在一些关键区别。
📘 过滤器(Filter)
在 Java 项目中,使用过滤器(Filter)的流程主要包括以下步骤:
1. 创建过滤器类
过滤器需要实现 javax.servlet.Filter
接口,并重写其中的三个方法:
init(FilterConfig filterConfig)
:用于初始化过滤器。
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
:核心逻辑处理方法。
destroy()
:用于销毁过滤器实例。
示例代码
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
| import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException;
@WebFilter("/*") public class MyFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("过滤器初始化"); }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("请求到达过滤器 - 前置处理");
chain.doFilter(request, response);
System.out.println("响应经过过滤器 - 后置处理"); }
@Override public void destroy() { System.out.println("过滤器销毁"); } }
|
2. 注册过滤器
方法一:使用注解
自 Servlet 3.0 开始,支持使用 @WebFilter
注解注册过滤器。注解的参数包括:
urlPatterns
:过滤器匹配的 URL 模式。
filterName
:过滤器名称(可选)。
dispatcherTypes
:指定过滤器适用的 Dispatcher 类型(如 REQUEST
或 FORWARD
)。
1 2 3 4
| @WebFilter(filterName = "MyFilter", urlPatterns = "/*") public class MyFilter implements Filter { }
|
这种方式简单直观,适用于轻量级配置。
方法二:通过 FilterRegistrationBean
注册(Spring 项目中)
在 Spring 项目中,过滤器通常通过配置类注册,使用 FilterRegistrationBean
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class FilterConfig {
@Bean public FilterRegistrationBean<MyFilter> registerMyFilter() { FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new MyFilter()); registration.addUrlPatterns("/*"); registration.setOrder(1);
return registration; } }
|
使用 FilterRegistrationBean
可以灵活配置过滤器,例如动态启用/禁用过滤器、注入依赖等。
方法三:配置在 web.xml
文件中
在传统的 Servlet 容器中,可以通过 web.xml
配置过滤器:
1 2 3 4 5 6 7 8
| <filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
|
这种方式适用于老版本的 Servlet 容器。
3. 使用过滤器处理请求和响应
在过滤器中,可以对请求和响应进行以下操作:
修改请求内容:
设置响应内容:
- 在响应返回给客户端之前,可以添加自定义头部、修改内容等。
示例:添加自定义头部
1 2 3 4 5 6 7 8 9 10
| @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("X-Custom-Header", "MyHeaderValue");
chain.doFilter(request, response); }
|
- 身份验证:
示例:身份验证过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response;
String authToken = httpRequest.getHeader("Authorization");
if (authToken == null || !authToken.equals("valid-token")) { httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); return; }
chain.doFilter(request, response); }
|
4. 控制过滤器执行顺序
如果有多个过滤器,可以通过优先级(order
)或 web.xml
配置的顺序来控制执行顺序。
示例:设置优先级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Bean public FilterRegistrationBean<FirstFilter> firstFilter() { FilterRegistrationBean<FirstFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new FirstFilter()); registration.addUrlPatterns("/*"); registration.setOrder(1); return registration; }
@Bean public FilterRegistrationBean<SecondFilter> secondFilter() { FilterRegistrationBean<SecondFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new SecondFilter()); registration.addUrlPatterns("/*"); registration.setOrder(2); return registration; }
|
5. 测试过滤器
测试方法:
- 运行应用程序。
- 发起 HTTP 请求(例如通过浏览器、Postman、curl)。
- 查看请求和响应,观察过滤器是否按照预期处理。
📘 拦截器(Interceptor)
定义:
拦截器(Interceptor
)是一种用于横切关注点的技术,通常与 AOP(面向切面编程)配合使用。它用于对特定方法进行前置、后置处理,不同于过滤器,它更多的是操作业务逻辑。
作用:
拦截器主要用于:
- 业务方法的前后处理:在方法执行之前或之后进行某些操作。
- 方法性能监控:记录方法执行的时间等信息。
- 事务管理:在方法执行之前或之后开启、提交或回滚事务。
实现:
拦截器通常通过实现 javax.interceptor.Interceptor
接口或继承 HandlerInterceptor
来实现。
在 Spring 框架中,拦截器通常通过实现 HandlerInterceptor
接口来创建,常见方法有:
preHandle()
:在请求处理之前执行。
postHandle()
:在请求处理之后,视图渲染之前执行。
afterCompletion()
:在整个请求处理完毕后执行。
配置:
拦截器一般通过 Spring 配置类来进行配置,或者通过注解的方式指定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Pre-Handle"); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Post-Handle"); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("After Completion"); } }
|
📊 过滤器与拦截器的区别
特性 |
过滤器(Filter) |
拦截器(Interceptor) |
定义 |
过滤器是基于 Servlet 技术的请求处理机制,专注于请求和响应的预处理和后处理。 |
拦截器通常是面向 AOP 的技术,专注于方法调用的前后处理。 |
工作范围 |
过滤器作用于 HTTP 请求和响应流的处理。 |
拦截器作用于 Java 方法的调用,通常与业务逻辑密切相关。 |
适用场景 |
请求和响应流的过滤、日志记录、身份验证、性能监控等。 |
业务方法的拦截、事务管理、缓存管理、权限验证等。 |
配置方式 |
配置在 web.xml 或使用 @WebFilter 注解。需要手动注册到 Spring 容器 |
配置在 Spring 配置类中,或使用 @Interceptor 注解(在 Java EE 中)。 |
执行顺序 |
过滤器按配置的顺序执行,适合在请求到达 Servlet 或响应离开之前进行全局处理。 |
拦截器在方法调用前后执行,适合在业务逻辑执行之前或之后进行处理。 |
处理逻辑 |
处理请求和响应的底层数据,例如修改请求或响应的内容。 |
处理业务方法的执行,例如修改方法参数或返回值。 |
💬 总结
- 过滤器更多关注 HTTP 请求和响应的处理,适用于横切关注点(如日志记录、性能监控、过滤等),并且与 Servlet 生命周期紧密相关。
- 拦截器主要用于方法调用的前后处理,更加专注于业务逻辑,适用于事务控制、权限验证等横切业务逻辑的任务。
根据你的项目需求,选择适合的技术来处理不同的横切关注点。