为什么DispatcherServlet不调用我的HandlerInterceptor?

时间:2017-01-13 23:35:27

标签: java spring-mvc interceptor

我知道在JavaEE中,过滤器可以拦截对servlet的任何请求。但Spring MVC中的拦截器并不完全相同。如果您查看下面的图表,您将看到Interpators位于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路径,但是当我向GET发出/login请求时,我知道它将失败,因为我处理/login映射的方法只接受POST个请求,但是在它抛出'405 Request方法'GET'不支持'错误之前,它应该至少首先击中我的拦截器?它没有。我不想将POST更改为GET。所以问题是为什么?

enter image description here

1 个答案:

答案 0 :(得分:2)

部分内容在

中解释

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

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

请注意javadoc个州

  

在适当的HandlerInterceptor之前调用HandlerAdapter   触发处理程序本身的执行。

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

您可能需要考虑使用Servlet Filter