HandlerInterceptor有一个对象处理程序参数,什么类型将被传递到拦截器?



HandlerInterceptor接口有一个参数Object handler,这意味着实现代码必须对处理程序对象进行类型检查才能使用它,并在适当的时候对其进行类型转换。

我发现的代码片段似乎假设处理程序总是一个HandlerMethod对象并返回true,如果情况并非如此,但我想了解为什么这似乎是一个常见的实现,使一个健壮的实现。

实现这个接口的标准方法似乎是:

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
// ...
return x; // whether or not to proceed with execution
}
return true; // fallback value in case handler wasn't a HandlerMethod
}
}

Spring javadoc似乎忽略了接口中有一个Object类型的事实,这对我理解这个接口非常没有帮助。

一些可能有助于我理解这个接口应该如何实现的问题:

  • 为什么是true一个明智的默认,如果我们得到一个处理程序,而不是我们期望的对象?
  • HandlerInterceptorhandler参数可以采用哪些类型?
  • 在什么情况下handler可能是不同的类型,如果有的话?
  • 为什么是Object而不是HandlerMethod参数?

基本上,handler参数可以是存在HandlerAdapter的任何类型。最常用的将是RequestMappingHandlerAdapter利用HandlerMethod

但是它可以是一个常规类、servlet甚至是一个函数(当使用函数方法时)。Spring Web Services也有一个实现和Spring集成。

Spring本身将支持以下开箱即用的

  • HandlerMethod
  • HandlerFunction
  • Controller
  • Servlet
  • HttpRequestHandler
  • WsdlDefinition(Spring Web Services)XsdDefinition(Spring Web Services)

所以不,它并不总是一个HandlerMethod,但它将是大多数用户。

HandlerInterceptor#preHandle()的javadoc说:

处理程序执行前的拦截点。在HandlerMapping确定合适的处理程序对象之后,但在之前调用HandlerAdapter调用处理程序.
DispatcherServlet处理一个处理程序在由任意数量的拦截器组成的执行链中,处理程序本身位于末尾。使用这个方法,每个拦截器可以决定中止执行链,通常发送HTTP错误或编写自定义响应。

这意味着拦截器根本不应该接触handler,所以它们不需要知道它的任何信息。他们唯一的工作是决定是否进一步通过请求。

BTW,org.springframework.web.servlet.*中没有一个标准HandlerInterceptor#preHandle()实现尝试分析真正的handler参数类型并基于它做任何逻辑。

为什么是Object而不是HandlerMethod参数?

来自org.springframework.web.servlet.HandlerMapping#getHandler()javadoc:

返回此请求的处理程序和任何拦截器。可以根据请求URL、会话状态或实现类选择的任何因素进行选择。
返回的HandlerExecutionChain包含一个处理程序对象,而不是一个标记接口,因此处理程序不受任何方式的约束。例如,可以编写HandlerAdapter来允许使用另一个框架的处理程序对象。

最新更新