Spring MVC 处理程序拦截器未运行。

4

我有以下拦截器类:

package cz.coffeeexperts.feedback.server.web.interceptors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class RestAuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler)
        throws Exception {

        System.out.println("fuu");
        response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
        return false;
    }
}

我在spring-webmvc.xml文件中如下配置:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <mvc:annotation-driven/>

    <mvc:interceptors>
     <mvc:interceptor>
       <mvc:mapping path="/rest/api/01/status" />
       <bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
     </mvc:interceptor>
    </mvc:interceptors>     

</beans>

然而,当我访问 http://localhost:8080/myserver/rest/api/01/status 时,我会得到一个状态码为200的普通响应(与添加拦截器之前相同)。此外,“fuu”消息未被打印(因此未调用 preHandle 方法)。
有什么想法吗?我是根据这个例子开始做的:http://javapapers.com/spring/spring-mvc-handler-interceptor/,但是所有其他例子看起来都一样,我找不出错在哪里。
我正在使用 Spring 3.2.4.RELEASE
重要修正,它可以工作:
<mvc:interceptors>
 <mvc:interceptor>
   <mvc:mapping path="/**" />
   <bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
 </mvc:interceptor>
</mvc:interceptors>  

所以问题是,我的路径出了什么问题?

有任何日志?错误?由于它的预处理,响应将被您的正常控制器方法覆盖,不是吗 - 预处理通常用于处理请求。 - NimChimpsky
没有任何反应,也没有错误提示,该方法没有被调用(就像我说的那样,没有输出System.out.println("fuu"))。另外,当您在preHandle中返回false时,它应该拦截控制器方法... - libik
当您删除映射时,拦截器是否起作用? - geoand
@geoand - 出现SAXError错误:找到了无效的内容,从元素'bean'开始。其中一个期望为'{"http://www.springframework.org/schema/mvc":mapping}'。 - libik
2
尝试这个:mvc:interceptors <bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" /> </mvc:interceptors> - geoand
@geoand - 很好的观点,我已经编辑了我的问题并附上了结果。 - libik
3个回答

4

好的,我已经找到了解决方案,因为我的路径是按照以下方式定义的:

<servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

以下是我的控制器的样子:

@Controller
@RequestMapping(value = "/api")
public class ApiController {
 @RequestMapping(value = "/01/status", method = RequestMethod.GET)
    @ResponseBody
    public ServerStatusJSON getStatus(HttpServletResponse response) {
        ...
    }
}

这个地址的有效配置为:http://localhost:8080/myserver/rest/api/01/status,其配置如下:

<mvc:interceptors>
 <mvc:interceptor>
   <mvc:mapping path="/api/01/status" />
   <bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
 </mvc:interceptor>
</mvc:interceptors>    

PS:感谢geoand,他帮助我找到了正确的方向。


1

我通过更改 mvc:mapping 的值来解决了这个问题。我的工作配置是:

    <mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.mmd.micro.common.TokenInterceptor">
            <property name="excludeUrls">
                <list>
                    <value>/app/token</value>
                </list>
            </property>
        </bean>
    </mvc:interceptor>
</mvc:interceptors>

1
作为libik的方法为什么有效的补充说明。正如他所提到的,他的控制器看起来像 -
@Controller
@RequestMapping(value = "/api")
public class ApiController {
 @RequestMapping(value = "/01/status", method = RequestMethod.GET)
    @ResponseBody
    public ServerStatusJSON getStatus(HttpServletResponse response) {
        ...
    }
}

同时也要记住,拦截器是在HandlerMapping级别上的。在这种情况下,它将是RequestMappingHandlerMapping(Spring 3.1+与mvc:annotation-driven)或DefaultAnnotationHandlerMapping。这里的映射将是/api/01/status,这正是他所做的。
<mvc:interceptors>
 <mvc:interceptor>
   <mvc:mapping path="/api/01/status" />
   <bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
 </mvc:interceptor>
</mvc:interceptors>   

如果您希望将其应用于所有模式,可以简单地执行<mvc:mapping path="/**"/> - 这将匹配所有URL(包括子路径),或者您可以为所有HandlerMappings调用拦截器。
<mvc:interceptors> 
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterc‌​eptor" /> 
</mvc:interceptors>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接