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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12114214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:38:24  来源:igfitidea点击:

What could be causing RequestMappingHandlerMapping to not register correctly?

javaxmlspringspring-mvc

提问by Brett Ryan

I'm trying to register a HandlerInterceptorAdapterinstance though no matter what I do it doesn't get executed.

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

I've tried copying the example from the spring documentationwith no luck.

我试过从 spring 文档中复制示例,但没有成功。

Could it be that <annotation-driven>is doing something that could be preventing my interceptor from being registered?

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

I tried removing the id from handlerMappingthough that only caused spring to register two instances in the container.

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

I've tried registering in both the root context and the servlet context.

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

Full servlet-context.xml

完整的 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:[email protected]"/>
        <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 doesn't do much

controller.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" />

Handler is as follows:

处理程序如下:

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) *** ");
    }

}

回答by Biju Kunjummen

Yes, you are right about <mvc:annotation-driven/>overriding the RequestMappingHandlerMapping that you have created with the custom interceptor registered through it. The way to register the interceptor is instead with a <mvc:interceptors..>:

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

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

Or if you want it at a specific mapping:

或者,如果您希望在特定映射中使用它:

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

If you want an explicit RequestMappingHandlerMapping, then you will also need to define the HandlerAdapter to go with it and remove mvc:annotation-driven

如果你想要一个显式的RequestMappingHandlerMapping,那么你还需要定义 HandlerAdapter 来使用它并删除mvc:annotation-driven