Spring 4.x官方参考文档中文版——第21章 Web MVC框架(14)
2016-06-22 15:45
281 查看
21.4 handler mappings(处理器映射)
在Spring前面的版本中,用户被要求在web应用的context中定义一个或多个HandlerMapping的bean,来把请求映射到合适的handler处理器上。在你认识了注解式controller以后,你一般就不需要这样做了,因为RequestMappingHanderMapping能够自动在所有@Controller的bean中寻找@RequestMapping注解。但是,请牢牢记住,所有HandlerMapping类是继承自AbstractHandlerMapping,并且拥有着以下的属性,以用来自定义它们的行为:
Interceptors(拦截器):列出所使用的拦截器。HandlerInterceptors在”21.4.1 使用HandlerInterceptor拦截请求”一章中讲过。
defaultHandler:默认使用的handler处理器,当handler处理器映射没有匹配到对应handler时使用。
order:基于order的属性值(详见org.springframework.core.Ordered接口),Spring把所有在context中可用的handler处理器映射进行排序,并使用第一个匹配的handler处理器。
alwaysUseFullPath:如果是true,Spring会在现有Servlet context中使用完整路径来寻找合适的handler处理器。如果是false(默认值),路径是基于现有Servlet映射的。例如:如果有一个Servlet,映射路径是”/testing/*”,并且alwaysUserFullpath属性被设置为true,那么他将使用”/testing/viewPage.html”,如果为false,将使用“/viewPage.html“。
urlDecode:默认为true,就如Spring2.5那样,如果你偏爱比较编码了的路径,把这个标识设置为false。然而,HttpServletRequest总是以解码形式暴露Servlet的路径。请注意,当在编码了的路径间比较时,Servlet路径是无法匹配的。
下面的例子展示了如何配置一个interceptor(拦截器):
21.4.1 使用HandlerInterceptor拦截请求
Spring的处理器映射机制就包括了handler处理器的拦截器,当你想要在特定请求中使用特定功能时,这个机制就会很有用。例如:checking for a principal(暂译:检查本金)。
位于handler处理器映射中的拦截器必须实现org.springframework.web.servlet包中的HandlerInterceptor。这个借口定义了三个方法:preHandle(..)会在指定handler处理器被执行前调用;postHandle(..)会在handler执行后调用;afterCompletion(..)会在请求被完整地完成后被调用。这3个方法应该可以满足所有前置处理和后置处理的各种类型的需求。
preHandle(..)方法返回一个布尔值,你能够使用这个方法来break(中断)或者continue(继续)这个执行链的处理过程。当这个方法返回true,handler处理器的执行链将继续;当返回false,DispatcherServlet就假定了拦截器已经处理过了这个请求(并且包括了比如:渲染了一个合适的视图之类的事),同时不继续执行其他拦截器,也不执行在执行链中的其他handler处理器。
拦截器能够使用interceptors属性来配置,这个属性存在于所有继承自AbstractHandlerMapping的HandlerMapping类中。如下例所示:
所有被此映射所处理的请求将被TimeBasedAccessInterceptor拦截。如果现在的时间在office hours(工作时间)之外,用户将被重定向到一个静态的HTML文件,这就表示,你只能在工作时间访问这个网站。
请注意:
当使用RequestMappingHandlerMapping时,这个handler处理器就是HandlerMethod的一个实例,以识别将要被调用的指定controller方法。
如你所见,Spring的适配器类:handlerInterceptorAdapter使继承HandlerInterceptor接口变得更加容易。
小提示:
在上面的例子中,这个被配置了的拦截器会在所有使用了注解式controller方法的请求处理过程中使用。如果你想要限制URL路径使用哪一个拦截器,你能够使用MVC 命名空间或者MVC Java配置,亦或声明一个MappedInterceptor类型的实例bean来指定之。详见”21.16.1 启用MVC Java配置或MVC XML命名空间”这一章节。
请注意,HandlerInterceptor的postHandle方法并不适合在使用了@ResponseBody和ResponseEntity的方法中使用。在这种情况下,HttpMessageConverter会在postHandler被调用前就写入并提交了这个响应,这样的话,postHandle就不能修改这个响应了,例如:你需要使用postHandle添加一个报头。更好的方法是:去实现ResponseBodyAdvice或者把它声明为一个@ControllerAdvice的bean,又或是直接在RequestMappingHandlerAdapter中配置来解决这个问题。
在Spring前面的版本中,用户被要求在web应用的context中定义一个或多个HandlerMapping的bean,来把请求映射到合适的handler处理器上。在你认识了注解式controller以后,你一般就不需要这样做了,因为RequestMappingHanderMapping能够自动在所有@Controller的bean中寻找@RequestMapping注解。但是,请牢牢记住,所有HandlerMapping类是继承自AbstractHandlerMapping,并且拥有着以下的属性,以用来自定义它们的行为:
Interceptors(拦截器):列出所使用的拦截器。HandlerInterceptors在”21.4.1 使用HandlerInterceptor拦截请求”一章中讲过。
defaultHandler:默认使用的handler处理器,当handler处理器映射没有匹配到对应handler时使用。
order:基于order的属性值(详见org.springframework.core.Ordered接口),Spring把所有在context中可用的handler处理器映射进行排序,并使用第一个匹配的handler处理器。
alwaysUseFullPath:如果是true,Spring会在现有Servlet context中使用完整路径来寻找合适的handler处理器。如果是false(默认值),路径是基于现有Servlet映射的。例如:如果有一个Servlet,映射路径是”/testing/*”,并且alwaysUserFullpath属性被设置为true,那么他将使用”/testing/viewPage.html”,如果为false,将使用“/viewPage.html“。
urlDecode:默认为true,就如Spring2.5那样,如果你偏爱比较编码了的路径,把这个标识设置为false。然而,HttpServletRequest总是以解码形式暴露Servlet的路径。请注意,当在编码了的路径间比较时,Servlet路径是无法匹配的。
下面的例子展示了如何配置一个interceptor(拦截器):
<beans> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <bean class="example.MyInterceptor"/> </property> </bean> <beans>
21.4.1 使用HandlerInterceptor拦截请求
Spring的处理器映射机制就包括了handler处理器的拦截器,当你想要在特定请求中使用特定功能时,这个机制就会很有用。例如:checking for a principal(暂译:检查本金)。
位于handler处理器映射中的拦截器必须实现org.springframework.web.servlet包中的HandlerInterceptor。这个借口定义了三个方法:preHandle(..)会在指定handler处理器被执行前调用;postHandle(..)会在handler执行后调用;afterCompletion(..)会在请求被完整地完成后被调用。这3个方法应该可以满足所有前置处理和后置处理的各种类型的需求。
preHandle(..)方法返回一个布尔值,你能够使用这个方法来break(中断)或者continue(继续)这个执行链的处理过程。当这个方法返回true,handler处理器的执行链将继续;当返回false,DispatcherServlet就假定了拦截器已经处理过了这个请求(并且包括了比如:渲染了一个合适的视图之类的事),同时不继续执行其他拦截器,也不执行在执行链中的其他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; } }
所有被此映射所处理的请求将被TimeBasedAccessInterceptor拦截。如果现在的时间在office hours(工作时间)之外,用户将被重定向到一个静态的HTML文件,这就表示,你只能在工作时间访问这个网站。
请注意:
当使用RequestMappingHandlerMapping时,这个handler处理器就是HandlerMethod的一个实例,以识别将要被调用的指定controller方法。
如你所见,Spring的适配器类:handlerInterceptorAdapter使继承HandlerInterceptor接口变得更加容易。
小提示:
在上面的例子中,这个被配置了的拦截器会在所有使用了注解式controller方法的请求处理过程中使用。如果你想要限制URL路径使用哪一个拦截器,你能够使用MVC 命名空间或者MVC Java配置,亦或声明一个MappedInterceptor类型的实例bean来指定之。详见”21.16.1 启用MVC Java配置或MVC XML命名空间”这一章节。
请注意,HandlerInterceptor的postHandle方法并不适合在使用了@ResponseBody和ResponseEntity的方法中使用。在这种情况下,HttpMessageConverter会在postHandler被调用前就写入并提交了这个响应,这样的话,postHandle就不能修改这个响应了,例如:你需要使用postHandle添加一个报头。更好的方法是:去实现ResponseBodyAdvice或者把它声明为一个@ControllerAdvice的bean,又或是直接在RequestMappingHandlerAdapter中配置来解决这个问题。
相关文章推荐
- 插件管理框架 for Delphi(一)
- 使用CSS框架布局的缺点和优点小结
- 一起动手编写Android图片加载框架
- 基于.NET平台常用的框架和开源程序整理
- 列举PHP的Yii 2框架的开发优势
- Windows窗体的.Net框架绘图技术实现方法
- 浅谈JavaScript 框架分类
- 轻量级javascript 框架Backbone使用指南
- javascript实现框架高度随内容改变的方法
- JS刷新框架外页面七种实现代码
- 超赞的动手创建JavaScript框架的详细教程
- 深入探讨前端框架react
- js验证框架实现代码分享
- jQuery的框架介绍
- 简单介绍不用库(框架)自己写ajax
- 利用ASP.NET MVC+EasyUI+SqlServer搭建企业开发框架
- asp.net4.0框架下验证机制失效的原因及处理办法
- 插件管理框架 for Delphi(二)
- 零基础学习AJAX之AJAX框架
- Ajax 框架学习笔记