什么可能导致RequestMappingHandlerMapping无法正确注册?

时间:2012-08-24 17:41:22

标签: java xml spring spring-mvc

我正在尝试注册一个HandlerInterceptorAdapter实例,但无论我做什么都不会被执行。

我尝试复制the example from the spring documentation没有运气。

可能是<annotation-driven>正在做一些可能阻止我的拦截器被注册的事情吗?

我尝试从handlerMapping中删除id,但这只会导致spring在容器中注册两个实例。

我尝试在根上下文和servlet上下文中注册。

完整的servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

  <!-- Configures the @Controller programming model -->
  <annotation-driven/>

  <beans:bean id="handlerMapping"
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <beans:property name="interceptors">
      <beans:list>
        <beans:ref bean="officeHoursInterceptor"/>
      </beans:list>
    </beans:property>
  </beans:bean>
  <beans:bean id="officeHoursInterceptor"
        class="com.johnsands.web.servlet.TimeBasedAccessInterceptor">
    <beans:property name="openingTime" value="9"/>
    <beans:property name="closingTime" value="18"/>
  </beans:bean>

  <!-- ReST Exception Handling
       http://www.stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1
       -->
  <beans:bean id="restExceptionResolver"
              class="com.stormpath.spring.web.servlet.handler.RestExceptionHandler">
    <beans:property name="order" value="100"/>
    <beans:property name="errorConverter">
      <beans:bean class="com.johnsands.spring.web.servlet.handler.BasicRestErrorConverter"/>
    </beans:property>
    <beans:property name="errorResolver">
      <beans:bean class="com.stormpath.spring.web.servlet.handler.DefaultRestErrorResolver">
        <beans:property name="localeResolver" ref="localeResolver"/>
        <beans:property name="defaultMoreInfoUrl" value="mailto:support@mycompany.com"/>
        <beans:property name="exceptionMappingDefinitions">
          <beans:map>
            <!-- 404 -->
            <beans:entry key="com.johnsands.api.ResourceNotFoundException" value="404, _exmsg"/>

            <!-- 500 (catch all): -->
            <beans:entry key="Throwable" value="500"/>
          </beans:map>
        </beans:property>
      </beans:bean>
    </beans:property>
  </beans:bean>

  <beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>

  <!-- Handles HTTP GET requests for /static/** by efficiently serving up static resources in the ${webappRoot}/static/ directory -->
  <resources mapping="/static/**" location="/static/" />

  <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
  <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
  </beans:bean>

  <!-- Imports user-defined @Controller beans that process client requests -->
  <beans:import resource="controllers.xml" />

</beans:beans>

controllers.xml没有做太多的事情

<!-- Maps '/' requests to the 'home' view -->
<mvc:view-controller path="/" view-name="home"/>
<mvc:view-controller path="/login" view-name="login" />
<mvc:view-controller path="/logout" view-name="logout" />

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.johnsands" />

处理程序如下:

public class TimeBasedAccessInterceptor
        extends HandlerInterceptorAdapter {

    private static final Logger log =
            LoggerFactory.getLogger(TimeBasedAccessInterceptor.class);
    private int openingTime;
    private int closingTime;

    public TimeBasedAccessInterceptor() {
        log.info(" *** Constructing Instance *** ");
    }

    public void setOpeningTime(int openingTime) {
        this.openingTime = openingTime;
    }

    public void setClosingTime(int closingTime) {
        this.closingTime = closingTime;
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        log.info(" *** (preHandle) *** ");
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (openingTime <= hour && hour < closingTime) {
            return true;
        } else {
            response.sendRedirect("http://www.google.com.au");
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView)
            throws Exception {
        log.info(" *** (postHandle) *** ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex)
            throws Exception {
        log.info(" *** (afterCompletion) *** ");
    }

}

1 个答案:

答案 0 :(得分:18)

是的,你正确地<mvc:annotation-driven/>覆盖了你通过它注册的自定义拦截器创建的RequestMappingHandlerMapping。注册拦截器的方法是使用<mvc:interceptors..>

<mvc:interceptors>
    <bean class=".."/>
</mvc:interceptors>

或者如果你想要它在特定的映射:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/test"/>
        <bean class="test"></bean>
    </mvc:interceptor>
</mvc:interceptors>

如果您想要一个明确的RequestMappingHandlerMapping,那么您还需要定义HandlerAdapter以使用它并删除mvc:annotation-driven