在 spring 框架中,过滤器(filter) 和 拦截器(interceptor) 都是用于处理 http 请求的中间件,但它们在作用范围、实现方式和生命周期上有显著区别。以下是详细对比和实现方式:
核心区别
| 特性 | 过滤器 (filter) | 拦截器 (interceptor) |
|---|---|---|
| 规范 | servlet 规范 (j2ee 标准) | spring 框架特有 |
| 作用范围 | 所有 web 资源(servlet、jsp、静态资源) | 仅 spring mvc 管理的 controller 请求 |
| 依赖 | 依赖 servlet 容器(如 tomcat) | 依赖 spring 容器 |
| 拦截时机 | 在请求进入 servlet 前 / 响应发送到客户端前 | 在请求进入 controller 前 / 后 / 视图渲染后 |
| 获取 spring bean | 不能直接获取(需通过工具类) | 可直接获取 spring bean |
| 异常处理 | 无法使用 spring 的异常处理机制 | 可结合 @controlleradvice 统一异常处理 |
实现方式
1. 过滤器 (filter) 实现
过滤器是 servlet 规范的一部分,通过实现 javax.servlet.filter 接口实现。
步骤:
- 创建 filter 类
import javax.servlet.*;
import java.io.ioexception;
public class customfilter implements filter {
@override
public void init(filterconfig filterconfig) {
// 初始化逻辑
}
@override
public void dofilter(servletrequest request, servletresponse response, filterchain chain)
throws ioexception, servletexception {
// 1. 请求到达 controller 前的逻辑
system.out.println("before controller (filter)");
// 放行请求
chain.dofilter(request, response);
// 2. 响应返回客户端前的逻辑
system.out.println("after controller (filter)");
}
@override
public void destroy() {
// 销毁逻辑
}
}- 注册过滤器(spring boot 中)
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<customfilter> customfilter() {
filterregistrationbean<customfilter> bean = new filterregistrationbean<>();
bean.setfilter(new customfilter());
bean.addurlpatterns("/*"); // 拦截所有路径
bean.setorder(1); // 执行顺序
return bean;
}
}2. 拦截器 (interceptor) 实现
拦截器是 spring mvc 的组件,通过实现 handlerinterceptor 接口。
步骤:
- 创建 interceptor 类
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.springframework.stereotype.component;
import org.springframework.web.servlet.handlerinterceptor;
import org.springframework.web.servlet.modelandview;
@component
public class custominterceptor implements handlerinterceptor {
@override
public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) {
// 在 controller 方法执行前调用
system.out.println("before controller (interceptor)");
return true; // true=放行, false=中断请求
}
@override
public void posthandle(httpservletrequest request, httpservletresponse response, object handler,
modelandview modelandview) {
// 在 controller 方法执行后、视图渲染前调用
system.out.println("after controller (interceptor)");
}
@override
public void aftercompletion(httpservletrequest request, httpservletresponse response,
object handler, exception ex) {
// 在整个请求完成后调用(视图渲染完毕)
system.out.println("after view render (interceptor)");
}
}- 注册拦截器
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.context.annotation.configuration;
import org.springframework.web.servlet.config.annotation.interceptorregistry;
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;
@configuration
public class interceptorconfig implements webmvcconfigurer {
@autowired
private custominterceptor custominterceptor;
@override
public void addinterceptors(interceptorregistry registry) {
registry.addinterceptor(custominterceptor)
.addpathpatterns("/**") // 拦截所有路径
.excludepathpatterns("/login"); // 排除路径
}
}执行顺序示例
假设请求路径被过滤器和拦截器同时拦截:
1. filter: dofilter() [前逻辑] 2. interceptor: prehandle() 3. controller 方法执行 4. interceptor: posthandle() 5. 视图渲染 6. interceptor: aftercompletion() 7. filter: dofilter() [后逻辑]
如何选择?
| 场景 | 推荐使用 |
|---|---|
| 全局日志、字符编码、安全过滤 | filter |
| 权限验证、参数预处理 | interceptor |
| 需要 spring 容器功能 | interceptor |
| 非 spring 项目 | filter |
最佳实践:优先使用 interceptor(可集成 spring 特性),若需处理静态资源或深度请求/响应修改,则用 filter。
到此这篇关于spring中过滤器和拦截器的区别及具体实现的文章就介绍到这了,更多相关spring过滤器和拦截器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论