【问题标题】:Spring HandlerInterceptor vs Servlet FiltersSpring HandlerInterceptor vs Servlet 过滤器
【发布时间】:2011-12-21 11:58:32
【问题描述】:

现在可以将 Spring 中的HandlerInterceptors 配置为仅在使用 <mvc:interceptors> 的特定 URL 上调用。

Servlet 过滤器可以实现相同的功能(日志记录、安全等)。那么应该使用哪一个呢?

我认为使用拦截器,可以使用ModelAndView 对象来处理模型,因此它具有更多优势。谁能画出过滤器或拦截器比另一个有优势的场景?

【问题讨论】:

标签: spring spring-mvc servlet-filters interceptor


【解决方案1】:

org.springframework.web.servlet.HanderInterceptor 接口JavaDoc 本身有两段讨论这个问题:

HandlerInterceptor 基本上类似于 Servlet 2.3 Filter,但 与后者相比,它只允许自定义预处理 禁止执行处理程序本身的选项,以及 自定义后处理。过滤器更强大,例如它们 允许交换传递的请求和响应对象 沿着链条。请注意,在 web.xml 中配置了一个过滤器,一个 应用程序上下文中的 HandlerInterceptor。

作为基本准则,细粒度处理程序相关的预处理任务 是 HandlerInterceptor 实现的候选者,尤其是 分解出的通用处理程序代码和授权检查。在 另一方面,过滤器非常适合请求内容和视图 内容处理,如多部分表单和 GZIP 压缩。这 通常显示何时需要将过滤器映射到某些内容 类型(例如图像)或所有请求。

【讨论】:

  • 所以现在我有 2 个观点。显然,上一篇文章表明 HandlerInterceptors 更强大。我知道 HandlerInterceptors 是 Spring Framework 的一部分,在 Spring 之外我不认为它们可以使用。但是在基于 Spring 的项目中,它们不是比过滤器更有优势吗?
  • @aces: 是的:springframework HanderInterceptor 的主要优点是——它们可以在控制器处理和视图渲染之间进行拦截,——它们是 spring Bean,因此很容易访问其他 spring bean。跨度>
【解决方案2】:

Spring Handler 拦截器允许您连接到请求生命周期的更多部分,并在流程中访问更多信息。它们通常比过滤器更紧密地与请求/响应周期耦合。

过滤器更适合将您的请求/响应视为黑盒系统。无论 servlet 是如何实现的,它们都可以工作。

如果您使用 Spring MVC,则几乎没有理由将新逻辑编写为 servlet 过滤器。过滤器能做的一切,拦截器能做的更轻松、更优雅。

还要记住,servlet 过滤器的存在时间比拦截器要长得多。

【讨论】:

  • 因此,在基于 Spring 的项目中,我们可以使用 Spring Handlerinterceptors,而不是使用过滤器来处理提供静态内容的 url。我确实同意您关于 HandlerInterceptors 比过滤器更强大的观点。但是你能想出一个应该使用过滤器的场景(基于弹簧的应用程序)吗?
  • @aces:我能想到的唯一场景是,如果您在同一个 webapp 中有多个 DispatcherServlet,并且您想拦截所有这些请求。不过,这种情况很少发生。
  • Spring Handler 拦截器不能做一件事——将请求/响应对象包装在自定义类型中。据我所知,您仍然需要一个过滤器。
  • @ErinDrummond 是正确的 - 自定义 ServletRequest 或 ServletResponse 方法实现的框架使用包装器并要求使用过滤器。 Spring HandlerInterceptors 不能这样做。
  • @skaffman - 我知道我提出了一个老问题,但是在想要计算请求时间的情况下,在请求过滤器中,我会错过请求花费的一些时间在框架中。这是否足以让我被 servlet 过滤器打扰,或者处理程序拦截器会给我一个足够准确的值?
【解决方案3】:

使用 Spring 拦截器,您可以访问可能有用的 Handler。此外,使用 Spring 拦截器,您可以在视图呈现之前和视图呈现之后访问执行逻辑。

【讨论】:

  • 过滤器(在 Servlet 中)可以更改从 Servlet 向客户端(浏览器)发送的响应。以同样的方式,当 Spring Controller 向客户端(浏览器)发送回响应时,我们可以更改响应或操作响应对象吗?如果答案是否定的,那么另一种方法是什么?我不想使用过滤器(在 Servlet 中)。
【解决方案4】:

Servlet Filter:

顾名思义,过滤器是由 servlet 容器为每个传入的 http 请求和每个 http 响应执行的 Java 类。这样,可以在 HTTP 传入请求到达资源之前对其进行管理,例如 JSP 页面、servlet 或简单的静态页面;以同样的方式可以在资源执行后管理 HTTP 出站响应。

此行为允许实现在许多不同上下文中重用的通用功能。

如上图所示,过滤器在 web 容器中运行,因此它的定义也将包含在 web.xml 文件中。

过滤器主要包括三种方法:

  1. init:执行以使用 init-param 元素初始化过滤器 过滤器定义。
  2. doFilter:对所有满足的 HTTP 传入请求执行 “网址模式”。
  3. destroy:释放过滤器使用的资源。

Interceptor:

Spring 拦截器类似于 Servlet 过滤器,但它们在 Spring 上下文中起作用,因此在管理 HTTP 请求和响应方面非常强大,但它们可以实现更复杂的行为,因为可以访问所有 Spring 上下文。

Spring 拦截器在 SpringMVC 上下文中执行,因此它们已在 rest-servlet.xml 文件中定义:

拦截器主要包括三个方法:

  1. preHandle:在目标资源执行之前执行。
  2. afterCompletion:在目标资源执行后执行 (在渲染视图之后)。
  3. postHandle:拦截处理程序的执行。

【讨论】:

  • 图表很有帮助
猜你喜欢
  • 2013-04-09
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 2016-10-19
  • 2015-11-11
  • 2013-11-11
  • 2017-02-21
相关资源
最近更新 更多