SpringBoot: Filters vs HandlerInterceptors

我们知道,在Java Web开发时,若想对请求或响应做出统一的逻辑处理,可以使用过滤器或者拦截器。那么具体什么时候使用过滤器,什么时候使用拦截器呢?

在探究这个问题之前,我们先搞清楚,什么是 Servlet ?

Servlet

现在我们通常做 Java Web 开发都会用 SpringBoot ,但要知道 SpringBoot 只是用来简化开发的,在此之前,Springframework 只是一个粘合剂框架,用来整合各种 Java Web 技术的,SpringMvc 都是出现的比较晚的技术,更早之前是 Struts2、Struts1。

那更早之前呢?就是基于原始的 Servlet/JSP 。

javax.servlet 和 jaavx.servlet.http 包提供了一些接口和类,实现了 Servlet 规范。javax.servlet 包中的 Servlet 声明了一些重要方法,如 init(), service(), desctroy() 等,这些也都是 servlet 的生命周期方法.

我们还知道,Servlet 是运行于 Servlet 容器中的。容器可以处理网络连接,解析 HTTP 请求等。Tomcat 就是最负盛名的一个容器。

虽然现在大家都用 Spring 全家桶做开发,但必须要知道 SpringWvc 的核心还是一个 DispatcherServlet,其本质也就是一个 Servlet.

过滤器 Filter

过滤器是被容器执行的类。请求在进入容器时、响应在离开容器时,会经过一个个的过滤器。过滤器的实例,在容器中是以过滤器链的形式执行的。

如果在应用中,我们定义了多个过滤器,那么执行的先后顺序,可以通过 @Order 注解来指定。

Filter 接口的核心方法,也是其生命周期方法:

  • init(FilterConfig config) - 此方法只调用一次,用于初始化过滤器
  • doFilter(HttpServletRequest request, HttpServletResponse response, FilterChian chian) - 此方法在每一个请求打到映射的资源上时都会调用,比如定义一个 Filter 拦截 /path/ ,那么每一个匹配 /path/ 访问资源的请求进来时,都会执行此方法。这个方法中就是拦截器的具体逻辑
  • destroy() - 此方法也只执行一次,用于销毁过滤器

拦截器 Interceptor

Spring 拦截器类似于 Servlet 过滤器。拦截器允许自定义预处理(Pre-Processing),在其中可以选择禁止对应 Handler 的执行;也允许自定义后处理(Post-Precessing);在拦截器中可以访问 Spring Context 上下文。

HandlerInterceptor 的核心方法:

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - 该方法在请求到达 Controller 之前执行操作,返回一个布尔值。当返回 false 时,不再执行对应的 handler
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) - 该方法在响应返回客户端之前执行
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) - 该方法在请求和响应流程完成之后执行
    HandlerInterceptor: 它的实例在 DispatcherServlet(javax.servlet.Servlet 的实例) 中作为请求处理的一部分来执行。

注意,现在实现 Spring 拦截器,只需要实现 HandlerInterceptor 接口即可,更早之前,接口的方法不能有默认实现时,是需要继承 HandlerInteceptorAdapter 这个抽象类的,现在这个类已经可以废弃了。

通过下面一张图看看过滤器和拦截器的位置:

Filters vs HandlerInterceptors
  • Filter 是 Servlet 规范中的,而 HandlerInterceptor 是 Spring 中的一个概念
  • 拦截器位置相对于过滤器更靠后
  • 精细的预处理任务适用于拦截器,如授权检查等
  • 内容处理相关或通用的流程,非常适合用过滤器;如上传表单、zip 压缩、图像处理、日志记录请求、身份验证等
  • HandlerInterceptor 的 postHandle 方法允许我们向视图添加更多模型对象,但不能更改 HttpServletResponse,因为它已经被提交了
  • 过滤器的 doFilter 方法比拦截器的 postHandle 更通用。我们可以在过滤器中改变请求或响应,并将其传递给链,甚至阻止请求的处理
  • HandlerInterceptor 提供了比过滤器更精细的控制,因为我们可以访问实际的目标 handler,甚至可以检查 handler 方法是否有某个特定的注解
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇