【问题标题】:Difference between Interceptor and Filter in Spring MVCSpring MVC中拦截器和过滤器的区别
【发布时间】:2021-07-17 12:22:05
【问题描述】:

我对@9​​87654323@ 和Interceptor 的用途有点困惑。

据我了解,Interceptor 在请求之间运行。另一方面,Filter 在渲染视图之前运行,但在控制器渲染响应之后运行。

那么,Interceptor 中的 postHandle() 和 Filter 中的 doFilter() 之间的区别在哪里?

应该在哪些用例中使用它的最佳实践是什么? 在这张图片中Filters 和Interceptors 工作在哪里?

【问题讨论】:

    标签: java spring spring-mvc spring-boot


    【解决方案1】:

    来自HandlerIntercepterjavadoc

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

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

    话虽如此:

    那么Interceptor#postHandle()Filter#doFilter()?

    postHandle 将在调用处理程序方法之后但在呈现视图之前调用。因此,您可以向视图添加更多模型对象,但您可以更改 HttpServletResponse,因为它已经提交。

    doFilterpostHandle 更通用。您可以更改请求或响应并将其传递给链,甚至阻止请求处理。

    此外,在preHandlepostHandle 方法中,您可以访问处理请求的HandlerMethod。因此,您可以根据处理程序本身添加预处理/后处理逻辑。例如,您可以为具有一些注释的处理程序方法添加逻辑。

    应该在哪些用例中使用它的最佳实践是什么?

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

    【讨论】:

    • 请注意,在 web.xml 中配置了一个过滤器,一个应用程序上下文中的 HandlerInterceptor ???你能解释一下吗?
    • Filter 与 Servlet API 有关,HandlerIntercepter 是 Spring 特定的概念。要注册 servlet 过滤器,您可以使用旧的 web.xml(Servlet 2.5 和更早版本)或新的编程方法(Servlet 3+)注册它。由于HandlerIntercepter 只是一个 Spring 抽象,你应该在 Spring 的上下文中注册
    • Filter 与 Servlet API 相关,而 HandlerIntercepter 是 Spring 特定的概念。纠正!但是无论您通过 web.xml 注册的内容是 WebApplication 的一部分,每个调度程序都是单个的,因此 servlet 和过滤器都与上下文相关联,将拦截器和过滤器与 rootContext 关联是一个好习惯,所以如果您使用多个调度程序所有人都可以共享。
    • 哪一个更适合 requst(body, headers) 日志记录?
    【解决方案2】:

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

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

    【讨论】:

    【解决方案3】:

    HandlerInterceptor 比过滤器为您提供更细粒度的控制,因为您可以访问实际的目标“处理程序”——这意味着您执行的任何操作都可能根据请求实际执行的操作而有所不同(而 servlet 过滤器是一般应用于所有请求 - 只能考虑每个请求的参数)。处理程序拦截器还提供了 3 种不同的方法,因此您可以在处理程序完成后但在视图呈现之前(甚至可以完全绕过视图呈现)或在视图本身被呈现之后,在调用处理程序之前应用行为。此外,您可以为不同的处理程序组设置不同的拦截器 - 拦截器在处理程序映射上配置,并且可能有多个处理程序映射。

    因此,如果您需要做一些完全通用的事情(例如记录所有请求),那么过滤器就足够了 - 但如果行为取决于目标处理程序,或者您想在请求处理和视图呈现之间做一些事情,那么 HandlerInterceptor 提供了这种灵活性。

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 1970-01-01
      • 2012-02-15
      • 2019-07-18
      • 2014-05-19
      • 2012-04-20
      • 2018-01-31
      • 2011-04-24
      相关资源
      最近更新 更多