我知道在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
。所以问题是为什么?
答案 0 :(得分:2)
部分内容在
中解释总之,DispatcherServlet
尝试使用HandlerMapping
为您的请求找到合适的处理程序(请参阅图形)。这些处理程序实际上是使用您已注册的拦截器包装实际处理程序方法(在本例中为@RequestMapping
注释方法)的适配器。如果找到此处理程序,则DispatcherServlet
可以继续,调用拦截器,并在需要时调用您的处理程序方法。
在您的情况下,因为您的@RequestMapping
仅限于POST请求并且您的请求是GET,DispatcherServlet
无法找到合适的处理程序,因此在它出现之前返回错误有机会调用任何拦截器。
请注意javadoc个州
在适当的
HandlerInterceptor
之前调用HandlerAdapter
触发处理程序本身的执行。
但您的DispatcherServlet
从未找到过处理程序。
您可能需要考虑使用Servlet Filter
。