为什么 DispatcherServlet 不调用我的 HandlerInterceptor?

Why doesn't DispatcherServlet invoke my HandlerInterceptor?

我知道在 JavaEE 中,过滤器可以拦截对 servlet 的任何请求。但是 Spring MVC 中的拦截器并不完全相同。如果您查看下图,您会发现拦截器位于 Dispatcher Servlet 之后。

在我提问之前,让我举个例子。

我有一个控制器,其中有 2 个方法映射到两个不同的请求。一个接受 GET 请求,另一个接受 POST 请求。现在,如果我在我的 Web 应用程序中添加一个拦截器,该拦截器将位于 Controller 之前。这意味着在命中控制器方法之前,首先 request 将命中我的拦截器的 preHandle 方法。

现在说在我的应用程序中,两个控制器方法如下所示:

@Controller
public class myController{

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test1(){      
    return "abc";
}

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String test1(){      
    return "xyz";
}

假设我有一个像这样的简单拦截器:

public class URLInterceptors extends HandlerInterceptorAdapter  {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("REQUESTED SERVLET PATH IS: " + request.getServletPath());   
        return true;    
    }   
}

现在,如果我向 /test 发出 GET 请求,我的拦截器将被命中并打印 servlet 路径,但是当我向 /login 发出 GET 请求时,我知道它会失败,因为我处理 /login 映射的方法只接受 POST 请求,但是在它抛出“405 请求方法 'GET' 不支持”错误之前,它至少应该首先命中我的拦截器?它没有。我不想把 POST 改成 GET。所以问题是为什么?

部分内容在

中有解释

总而言之,DispatcherServlet 尝试使用 HandlerMapping 为您的请求找到合适的处理程序(参见您的图形)。这些处理程序实际上是将实际处理程序方法(在本例中为 @RequestMapping 注释方法)与您注册的拦截器包装起来的适配器。如果找到此处理程序,则 DispatcherServlet 可以继续,调用拦截器,并在需要时调用您的处理程序方法。

在您的情况下,因为您的 @RequestMapping 仅限于 POST 请求并且您的请求是 GET,DispatcherServlet 无法找到合适的处理程序,因此 returns 在它有机会调用任何拦截器之前发生错误。

请注意 javadoc 状态

A HandlerInterceptor gets called before the appropriate HandlerAdapter triggers the execution of the handler itself.

但您的 DispatcherServlet 从未找到处理程序。

您可能要考虑改用 Servlet Filter