我们说的 Filter 和 Interceptor 是啥?
- Filter:javax.servlet.Filter
- Interceptor:org.springframework.web.servlet.HandlerInterceptor
参考:
简介
Filter
public interface Filter { public void init(FilterConfig filterConfig) throws ServletException; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; public void destroy(); }
根据代码附属的文档:
Filter 用于过滤对资源的请求和响应。一个Filter可以同时用于过滤请求和响应。
目标资源可以是 Servlet 或 静态资源。
Filter 的 doFilter 方法执行具体的过滤操作。
Filter 可以通过 FilterConfig 对象获取初始化参数。还可通过 FilterConfig 提供的 ServletContext 引用获取更多资源信息用于过滤操作。
可通过 web descriptor 文件 web.xml 配置Filter,也可以用 @WebFilter 注解配置。
(标准的默认 web descriptor 文件是 WEB-INF/web.xml)
典型使用场景:
- 身份验证
- 日志、审计
- 图像转换
- 数据压缩
- 加解密
- 访问令牌处理
- 触发资源访问事件2
- XSL 转换(XSL/T)
- Mime 类型链式过滤
HandlerInterceptor
public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
根据代码附属文档:
HandlerInterceptor 用于自定义执行链。
HandlerInterceptor 会在相应的 HandlerAdaptor 被调用前执行,所以可用于“预处理”。
例:授权检查、区域设置、主题更改 等。
它的主要目的就是提取出可复用的 Handler 代码。
作为Spring中的概念,HandlerInterceptor 可以像一般的Bean那样配置在 Application Context 中。
HandlerInterceptor 与 Servlet Filter 很相似。
但是 Interceptor 只允许通过预处理禁止 Handler 本身运行,或执行一些后续处理(post-processing)。
Filter 更强大。如,允许交换传递给后续处理链的 request 和 response 对象。
基本准则:
- 细粒度的 Handler相关 预处理操作 可以用 HandlerInterceptor 实现。
尤其是 授权检查 和 公用的 Handler 代码。 - Filter 适合用于处理 request 和 view 内容。如,Multipart 表单、Gzip压缩。
典型的作法就是处理特定的 Content-Type。
对比
最本质的区别是,Filter 是 Servlet 中的概念,HandlerInterceptor 是 Spring Web 中的概念。
它们是两个不同体系中的概念。因为它们都能实现对 HTTP Request 和 Response 的一些自定义处理,所以会被一些无聊的人强行拿来作比较,甚至成为考题。
其实在一些常见业务常见中,两种技术实现方式并不存在孰优孰劣。只有结合具体业务场景,才能真正比较出哪种方式更合适。
Filter 相关流程
HandlerInterceptor 相关流程
现在的编程模式都是 遇到 新型 业务需求时先搜索一下别人是如何实现的。
我认为这是最普遍、性价比最高、几乎每个人都默认使用、对个人自身成长提升最快的模式。
注意我的用词“新型”。没有人天生就会;自己埋头苦研,不借助巨人力量的,都是傻子;而且肯定不会得到值得推广的成功。编程就是“抄”!
只要清楚它们在 HTTP Request Response 流程中的角色,看到别人给的常规实现方式,就自然会明白 为什么选其中一种而不选另一种。
示例:HandlerInterceptor 用于授权检查
每个项目可能有自己独特的授权检查需求。此示例仅供参考。
很多项目会用Session来存放用户信息(Session可能存储在Redis等中间件中,以实现分布式架构)
RequestContext:存储用户信息的帮助类
此处使用 ThreadLocal 存储的用户信息,不用担心OOM。因为:
- 我们会在后续的HandlerInterceptor中清理用户信息
- 即使清理时遇到异常,线程中的用户信息也不会无限增长。
线程接到下一次用户请求时相关信息又会被设置为新请求的数据
public abstract class RequestContext { private static final ThreadLocal userIdHolder = new ThreadLocal(); // 可根据需要添加各种用户信息字段 public static String getUserId() { return userIdHolder.get(); } public static void setUserId(String id) { userIdHolder.set(id); } public static void clear() { userIdHolder.remove(); } }
AuthInterceptor:执行授权检查
public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler) { // 从 response 获取用户相关标识,并进行授权检查 ... // 通过授权检查,并获得 User ID。如果未通过,可设置response相关内容,并返回 false String userId = ... // 保存用户信息,供后续 Controller 业务使用 RequestContext.setUserId(userId); } @Override public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { // 清除之前保存的用户信息。 // 为什么在 afterCompletion() 方法中清理,而不是在 postHandle() 中? // 因为如果业务代码中抛出异常,将跳过 postHandle() 方法,但不会跳过 afterCompletion(). // 详见 DispatcherServlet.doDispatch() 方法 RequestContext.clear(); } }
应用 AuthInterceptor
@Configuration public class MyWebAppConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/**"); } }
使用Request用户信息
@RestController public class TestController { @GetMapping("test") public void test() { String userId = RequestContext.getUserId(); ... } }
相关推荐
Java WEB 篇九 Java servlet、filter、listener、interceptor 之间的区别和联系?
数据验证:HTML5 的原生验证模式、Struts2 的 Validation 验证框架以及 Interceptor 拦截器、JavaEE 的 Filter 过滤器 学生端(修改个人信息、修改密码、查看成绩) 教师端(成绩查看与修改、录入成绩、所教科目管理...
本资源实现java web项目中常见的三种组件:Filter[过滤器]、Listener[监听器]、Interceptor[拦截器]。就一个Controller层实例,对于初学者而言,是个不错的选择
SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。 配置applicationContext-shiro.xml 1. 配置authorizingRealm ...
过滤器 filter web.xml implements filter filterchain arg2.doFilter(req,resp); 监听器 servlet application /session /request 6/8 个 1、拦截器 定义拦截器的包 定义拦截器的核心 定义拦截器类 ...
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <param-name>targetFilterLifecycle <param-value>true </filter> <filter-mapping> <filter-name>shiro...
以及最早学习到的java web中的javax.servlet.Filter的概念, 都是一种链式的处理流程,这一个环节处理完成,然后处理另一个环节,这样就可以在一个处理本身的之前和之后做一些事情了。 比如说,struts2中Action在...
过滤器--是在java web中,提前过滤掉一些信息或者提前设置一些参数,然后再传入servlet/struts的 action进行业务逻辑处理。比如过滤掉非法url或者在传入servlet/struts的action前统一设置字符集,或者去除掉一些非法...
第1章 Java Web应用开发简介 1 1.1 Java EE应用概述 1 1.2 Java EE概念 1 1.2.1 Java EE多层模型 1 1.2.2 Java EE体系结构 2 1.3 Java EE的核心API与组件 4 1.4 Web服务器和应用服务器 13 1.5 小结 16 第2章 建立...
idea软件。SpringBoot的拦截器的博客所写的例子。preHandle()方法的返回值true和false的详细区别还未描述
本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本: •Struts 1.2 •Spring 1.2.5 •Hibernate 3.0 本文选用的数据库为Oracle 9i,当然你可以在不...
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> 这个设置是主要...
Filter首先在DispatcherServlet的前面运行,而Interceptor在DispatcherServlet和Controllr(Handler)之间运行。 筛选 Web应用程序上下文功能 使用Spring函数困难 通常,实现编码,CORS,XSS,LOG,证书,授权等。 ...
本课程在技术栈层面涵盖了“用户身份认证”、“接口鉴权”等业务场景常用的大部分技术,包括Spring Boot2.x、Spring MVC、Mybatis、加密解密算法AES、雪花算法Snowflake、统一验参工具ValidatorUtil、JWT(Json Web ...
现在有很多Java的Web框架可供选择,并且它们也都是免费的。例如: • Struts • Webwork • Tapestry • Spring MVC 以上框架都是非常优秀的。说实话,如果阿里巴巴网站在2001年开始,就有这么多可选择的话,...