简体   繁体   English

为什么DispatcherServlet不调用我的HandlerInterceptor?

[英]Why doesn't DispatcherServlet invoke my HandlerInterceptor?

I know that in JavaEE, filters can intercept any request to a servlet. 我知道在JavaEE中,过滤器可以拦截对Servlet的任何请求。 But Interceptors in Spring MVC are not exactly the same. 但是Spring MVC中的拦截器并不完全相同。 If you look at the diagram below, you will see that Interceptors come after Dispatcher Servlet. 如果查看下面的图,您会发现拦截器位于Dispatcher Servlet之后。

Let me give you an example before I ask my question. 在问我问题之前,让我举一个例子。

I have a controller, which has 2 methods in it that are mapped to two different requests. 我有一个控制器,其中有2个映射到两个不同请求的方法。 One accepts GET requests and other accepts POST requests. 一个接受GET请求,另一个接受POST请求。 Now if I add an interceptor in my web application, that interceptor will sit before Controller. 现在,如果我在Web应用程序中添加了一个拦截器,则该拦截器将位于Controller之前。 Meaning that before controller method is hit, first a request will hit my interceptor's preHandle method. 这意味着在命中控制器方法之前,首先将有一个request命中我的拦截器的preHandle方法。

Now say that in my app, two controllers methods look like this: 现在说在我的应用程序中,两个控制器方法如下所示:

@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";
}

And lets say I have a simple interceptor like this: 可以说我有一个像这样的简单拦截器:

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;    
    }   
}

Now, if I make a GET request to /test , my interceptor is hit and it prints the servlet path, but when I make a GET request to /login , I know it will fail because my method that handles /login mapping accepts only POST requests, however before it throws '405 Request method 'GET' not supported' error, it should at least hit first my interceptor? 现在,如果我向/test发出GET请求,则会命中我的拦截器并打印servlet路径,但是当我向/login发出GET请求时,我知道它将失败,因为我处理/login映射的方法仅接受POST请求,但是在引发“ 405请求方法'不支持'GET”错误之前,它至少应该首先命中我的拦截器? It doesn't. 没有。 II don't want to change POST to GET . II不想将POST更改为GET So the question is why? 那么问题是为什么呢?

在此处输入图片说明

Part of this is explained in 其中的部分说明

In summary, the DispatcherServlet attempts to find an appropriate handler for your request by using a HandlerMapping (see your graphic). 总之, DispatcherServlet尝试通过使用HandlerMapping (请参见图形)为您的请求找到合适的处理程序。 These handlers are actually adapters that wrap the actual handler method (a @RequestMapping annotated method in this case) with the interceptors you've registered. 这些处理程序实际上是将实际的处理程序方法(在这种情况下为@RequestMapping注释的方法)与已注册的拦截器包装在一起的适配器。 If this handler is found, then the DispatcherServlet can proceed, invoke interceptors, and, if required, invoke your handler method. 如果找到此处理程序,则DispatcherServlet可以继续进行,调用拦截器,并在需要时调用您的处理程序方法。

In your case, because your @RequestMapping is restricted to POST requests and your request is a GET, the DispatcherServlet fails to find an appropriate handler and therefore returns an error before it's had a chance to invoke any interceptors. 在您的情况下,由于@RequestMapping仅限于POST请求,而您的请求是GET,因此DispatcherServlet无法找到合适的处理程序,因此在有机会调用任何拦截器之前会返回错误。

Note that the javadoc states 请注意, javadoc声明

A HandlerInterceptor gets called before the appropriate HandlerAdapter triggers the execution of the handler itself. 在适当的HandlerAdapter触发处理程序本身的执行之前,将调用HandlerInterceptor

but your DispatcherServlet never found a handler to begin with. 但是您的DispatcherServlet从未找到一个开始的处理程序。

You might want to consider using a Servlet Filter instead. 您可能需要考虑使用Servlet Filter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM