概述
在Spring之前的版本中,用户必须定义一个或者多个HandlerMapping
bean在web应用容器中用来映射web请求到合适的handlers。自从引进了注解控制器,你通常不再需要这样做了.因为standardAsyncRequestConstructor会自动寻找所有标注了@Controller
中标记了@RequestMapping
.可是记住所有的HandlerMapping
类都继承自AbstractHandlerMapping
。在AbstractHandlerMapping
类中你可以自定义以下的属性:
interceptors
.定义拦截器列表.下面会介绍.defaultHandler
.定义默认的handler,当DispatcherServlet找不到默认的handler就会使用这个默认的handler.order
.基于顺序属性的值(具体可以看org.springframework.core.Ordered
).Spring会排序找到的所有handler mappings.并将它们排序,并应用第一个匹配的处理程序。alwaysUseFullPath
.当这个值为true
时,Spring在当前Servlet容器中会使用绝对路径会查找合适的handler.如果是false
(默认值),path会使用当前Servlet的相对路径。例如,如果一个Servlet使用/testing/*
来映射并且alwaysUseFullPath
的属性设置为true.会查找到/testing/viewPage.html
,反之如果这个属性设置为false的话,/viewPage.html
这个路径将会匹配到.urlDecode
.默认是true
.在Spring2.5中,如果你喜欢比较编码路径,设置这个值为false
.但是,HttpServletRequest
总是以解码形式在form中暴露Servlet路径.请注意,Servlet路径不会匹配编码后的路径。
下面的例子是展现如何配置一个interceptor:
<beans>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="interceptors">
<bean class="example.MyInterceptor"/>
</property>
</bean>
<beans>
1、使用HandlerInterceptor拦截request
Spring的handler mapping机制包含handler拦截器.当你想要到某些request应用一些特殊的功能的时候,拦截器非常有效.例如,身份验证.
在handler mapping中的拦截器必须实现org.springframework.web.servlet包下面的HandlerInterceptor
.这个接口定义了3个方法:
1. preHandle(..)
:当真实的handler被执行之前会调用此方法.
2. postHandler(..)
:当handler被执行之后会调用此方法.
3. afterCompletion(..)
:当完整的request完全之后会调用此方法.
这三个方法提供足够的灵活性来做各种各样的预处理和后处理。
preHandle(..)
方法返回一个boolean值.你可以使用这个方法来打断或者继续处理的执行链.当这个方法返回true的时候,这个handler的执行链将会继续执行;当这个这个方法返回值为false时,DispatcherServlet
会假设拦截器已经处理了request(例如:渲染一个合适的页面).并且不会继续执行其它的拦截器和执行链当中真实的handler.
拦截器可以使用interceptors
属性来配置,它会出现在所有继承于AbstractHandlerMapping
的HandlerMapping
的类中.下面展现一个简单的例子:
配置:
<beans>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="interceptors">
<list>
<ref bean="officeHoursInterceptor"/>
</list>
</property>
</bean>
<bean id="officeHoursInterceptor"
class="samples.TimeBasedAccessInterceptor">
<property name="openingTime" value="9"/>
<property name="closingTime" value="18"/>
</bean>
<beans>
时间拦截器:
package samples;
public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
private int openingTime;
private int closingTime;
public void setOpeningTime(int openingTime) {
this.openingTime = openingTime;
}
public void setClosingTime(int closingTime) {
this.closingTime = closingTime;
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
Calendar cal = Calendar.getInstance();
int hour = cal.get(HOUR_OF_DAY);
if (openingTime <= hour && hour < closingTime) {
return true;
}
response.sendRedirect("http://host.com/outsideOfficeHours.html");
return false;
}
}
所有的request都会被TimeBasedAccessInterceptor
拦截处理.如果当前时间不在办公时间,用户会被重定向到规定的静态页面中.并且这个文件可以定义成:你只能够在工作时间访问这个网站.
注意:当使用RequestMappingHandlerMapping
时,真实的处理器是HandlerMethod的实例.在之前的Blog —> Spring MVC 之 @RequestMapping 中有具体的解析.感兴趣的朋友可以去看一看.这个HandlerMethod
的实例会映射到特殊的Controller方法去调用handler方法.
你可以看到,Spring中的配置类HandlerInterceptorAdapter
使用很容易的去继承HandlerInterceptor
接口.
注意:HandlerInterceptor
的postHandle
方法通常不适合于@ResponseBody
和ResponseEntity
方法.在这种情况下,HttpMessageConverter
将会在postHandle
被执行之前就会写入response并提交.这样就可能改变response,例如添加一个header.你可以通过实现ResponseBodyAdvice
或者声明它为一个@ControllerAdvice
的bean或者直接在RequestMappingHandlerAdapter
去配置它。
因为水平有限,翻译不足之处还望见谅。
原文地址:spring-framework-reference-4.2.6.RELEASE
最后
以上就是怕孤单马里奥为你收集整理的8、Spring MVC 之 Handler mappings的全部内容,希望文章能够帮你解决8、Spring MVC 之 Handler mappings所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复