spring Handler 映射
来源:互联网 发布:青山水利造价软件 编辑:程序博客网 时间:2024/06/09 16:18
Spring 的前几个版本,开发者都需要在 web 应用的上下文定义(多个) HandlerMapping
bean,用来将 web 请求映射到指定的 handler。可当引入注解控制器时,开发者基本不再需要这样配置。因为 RequestMappingHandlerMapping
会自动寻找所有 @Controller
bean 中的 @RequestMapping
注解。另外提醒一下,所有从 AbstractHandlerMapping
继承过来的 HandlerMapping
类,都以通过设置以下属性来自定义其行为:
interceptors
拦截器链。HandlerInterceptor
s 会在 Section 16.4.1, “使用 HandlerInterceptor 拦截请求” 谈论。defaultHandler
默认 handler。此 handler 不影响其他 handler 的使用。order
order 属性 (可查看org.springframework.core.Ordered
接口), Spring会对可匹配的 handler 进行排序,并应用第一个匹配到 handler。alwaysUseFullPath
当此属性为true
时,Spring 会使用当前 Servlet 上下文的全路径去寻找合适的 handler。当为false
时(默认值),Spring 会使用相对路径来寻找合适的 handler。举个例子,当 某个 Servlet 映射/testing/*
请求时,若alwaysUseFullPath
属性为true
,会使用/testing/viewPage.html
;反之,使用/viewPage.html
。urlDecode
从 Spring 2.5 开始,此属性默认为true
。如果你更需要编码路基路径,可将此属性设置为 true。然而,HttpServletRequest
总会暴露解码后的 Servlet 路径。另外注意的是,当比较编码后的路径时,Servlet 路径是不会再匹配的。
如下例子,演示了如何配置一个拦截器:
<beans> <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <bean class="example.MyInterceptor"/> </property> </bean><beans>
16.4.1 使用 HandlerInterceptor 拦截请求
Spring 的 handler 映射机制包含了 handler 拦截器。使用handler 拦截器,可以在某些的请求中应用的特殊的功能,比如说,检查权限。
handler 映射的拦截器必须实现 HandlerInterceptor
接口(此节接口位于 org.springframework .web.servlet
包中)。这个接口定义了三个方法:preHandle(..)
在 handler 执行前调用;postHandle(..)
在handler 执行后调用;afterCompletion(..)
在整一个请求完成后调用。这三个方法基本足够应对各种预处理和后处理的状况。
preHandle(..)
方法返回一个 boolean 值。你可以使用这个方法来中断或继续处理 handler 执行链。当此方法返回 true
时,hadler 执行链会继续执行;反之,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; }}
通过这样的配置,所有请求 handler 都会被 TimeBasedAccessInterceptor
拦截。如果当前时间是下班时间,用户会重定向到一个静态页面,换句话说就是,你只能在上班时间访问该网站。
[提示]
当使用 RequestMappingHandlerMapping
时,真实的 handler 是一个HandlerMethod
实例,该实例指定了会被调用的控制器方法。
如你所见,Spring 的适配器类 HandlerInterceptorAdapter
,使继承 HandlerInterceptor
接口变得更加简单。
在上述例子中,所配置的拦截器会应用到所有带注解的请求处理器。如果需要缩窄拦截器的拦截 url 路径范围,可以使用 MVC 命名空间或 MVC Java 配置,或声明 MappedInterceptor
类型的 bean 来缩窄拦截器的拦截范围,详情可参考 Section 16.16.1, “启用 MVC Java 配置或 MVC XML 命名空间”。
注意,HandlerInterceptor
的 postHandle
方法不一定适用于@ResponseBody
和ResponseEntity
方法。在这种情况下,HttpMessageConverter
实例会在 postHandle
方法执行之前就将数据写到 response 并提交 response,所以 postHandle
方法不可能再处理 response(如添加一个 Header)。相反,应用程序可以实现 ResponseBodyAdvice
,将其声明为 @ControllerAdvice
bean 或将其直接在 RequestMappingHandlerAdapter
中配置它。
- spring Handler 映射
- Spring MVC教程 映射处理器Handler Mapping
- 第三集 Spring MVC教程 映射处理器Handler Mapping
- Spring-mvc-Handler的返回值用法以及URL映射
- spring mvc注解的处理器适配器为什么不能处理非注解的处理器映射器映射的handler
- Spring官方文档翻译——15.4 处理器映射(Handler mappings)
- Spring MVC学习笔记3,三种映射方式得到Handler
- Spring 映射
- spring MVC handler
- spring-rest-exception-handler
- Spring handler method
- Spring MVC Handler Interceptor
- SpringMVC的Handler处理及url映射
- SpringMVC的Handler处理及url映射
- SpringMVC的Handler处理及url映射
- SpringMVC的Handler处理及url映射
- spring mvc url映射
- spring-映射关系
- Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
- docker + shellshocker
- 运算符和表达式
- php: CGI faseCGI PHP-FPM | laravel启动过程 | php依赖注入
- Spring事务管理
- spring Handler 映射
- Java NIO (3) Selector
- 解决eclipse neno在线下载安装缓慢及失败的问题
- 架构学习之路——高可用高并发系统设计原则
- 学习Weblogic的学习之一
- python——高阶函数——闭包 装饰
- intellij idea maven 使用
- Search Insert Position
- java将16进制与10进制互相转换