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
What could be causing RequestMappingHandlerMapping to not register correctly?
提问by Brett Ryan
I'm trying to register a HandlerInterceptorAdapter
instance 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 handlerMapping
though 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