SpringMVC 拦截器 Interceptor 男娘i 2023-01-21 05:27 117阅读 0赞 ## SpringMVC Interceptor ## > API: http://docs.spring.io/spring-framework/docs/3.2.4.RELEASE/javadoc-api/org/springframework/web/servlet/HandlerInterceptor.html > DOCS: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/\#mvc-handlermapping-interceptor > Blog: http://haohaoxuexi.iteye.com/blog/1750680 ## Interceptor 概要 ## ### 接口原型 ### Spring 的 Interceptor (拦截器)是通过 HandlerInterceptor 接口实现的。 package org.springframework.web.servlet; public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; } Spring 的 handle mapping(处理器映射)机制包含handler interceptors(处理拦截器),当你需要需要对某一请求应用特定的功能时,拦截器会变得很有用,例如身份检查。 位于处理映射中的拦截器必须实现 org.springframework.web.servlet 包下的 HandlerInterceptor 接口。这个定义了三个方法: * **preHandle(…)** 会在实际的 handler 执行之前被调用。 * **postHandle(…)** 会在 handler 执行之后被调用。 * **afterCompletion(…)** 会在**整个请求完成** 之后被调用。 这三个方法为各种 preprocessing 和 postprocessing (前处理和后处理)提供了足够的灵活性。 > 说明:preHandle(…)方法返回一个布尔值,你可以使用这个方法来中断或继续执行 execution chain(执行链)。当此方法返回 true, handler 执行链会继续执行;当返回 false,DispatcherServlet 认为拦截器自身已经完成了对请求的处理(例如,呈现一个适当的视图),就不会继续执行其他拦截器,也不会执行执行链中的实际的 handler。 #### preHandle API #### 拦截 handler 的执行。在 HeandlerMapping 决定了一个合适的 handler 对象之后,但在 HandlerAdapter 调用 handler 之前被调用。 DispatcherServlet 处理 execution chain(执行链)中的 handler,执行链由数个拦截器组成,handler 在执行链的最后。通过此方法,每一个拦截器都可以决定放弃后面的执行链,典型地做法如:发送一个HTTP错误,或写入一个自定义响应。 返回值: true:如果执行链要处理下一个拦截器或handler。否则,DispatcherServlet 假定此拦截器自己已处理了响应。 #### postHandle API #### 拦截 handler 的执行。在 HandlerAdapter 实际调用 handler 之后,但在 DispatcherServlet 渲染 view 之前被调用。可以暴露额外的 modle 对象到参数中的 ModelAndView。 DispatcherServlet 处理 execution chain(执行链)中的 handler,执行链由数个拦截器组成,handler 在执行链的最后。通过此方法,每一个拦截器都可以执行一个后处理,按执行链顺序的逆序执行。 #### afterCompletion API #### 完成请求处理之后的回调,在渲染 view 之后。将在任何 handler 执行结果上调用,因此允许做适当的资源清理。 注意:只在拦截器的 preHandle 方法成功执行完成且返回 true 时才被调用! 与 postHandle 方法一样。此方法按拦截器在执行链中的顺序逆序调用。因此第一个拦截器(的此方法)将在最后被调用。 ### Interceptor 实现 ### #### 方式一:实现 HandlerInterceptor 接口 #### public class FirstInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor ... preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor ... postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor ... afterCompletion"); } } #### 方式二:实现 WebRequestInterceptor 接口 #### WebRequestInterceptor 是另外一个接口。原型是: package org.springframework.web.context.request; public interface WebRequestInterceptor { void preHandle(WebRequest request) throws Exception; void postHandle(WebRequest request, ModelMap model) throws Exception; void afterCompletion(WebRequest request, Exception ex) throws Exception; } ##### preHandle 方法 ##### 在请求的 handler 调用之前拦截执行。 允许在此时准备上下文资源(比如 Hibernate Session),把它们暴露到 request attributes 中,或者暴露为 thread-local 对象。 ##### postHandle 方法 ##### 在请求的 handler 成功执行之后,在 view 渲染之前,拦截执行。 允许在 handler 执行成功之后,修改上下文资源(例如:清除 Hibernate Session)。 ##### afterCompletion 方法 ##### view 渲染之后的回调。将在 handler 执行的结果上调用,因此允许此时做是的适当的资源释放。 注意:仅在此拦截器的 preHandle 方法成功执行完成的情况下被调用! ### 说明 ### * preHandle方法:方法的返回值为 void,不同于 HandlerInterceptor,一般被用于资源准备工作。可以调用 WebRequest 的 setAttribute(name, value, scope) 方法把相关资源放入 WebRequest 的属性中。其中的 scope 作用域值可以为: * WebRequest.SCOPE\_REQUEST:值为0,代表仅在在 request 中访问。 * WebRequest.SCOPE\_SESSION:值为1,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。 * WebRequest.SCOPE\_GLOBAL\_SESSION:值为2,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。 * postHandle方法:可以在这个方法里面通过改变数据模型 ModelMap 来改变数据的展示。参数: * WebRequest: 是用于传递整个请求数据的,比如在 preHandle 中准备的数据都可以通过 WebRequest 来传递和访问。 * ModelMap: 就是 Controller 处理之后返回的 Model 对象,我们可以通过改变它的属性来改变返回的 Model 模型。 * afterCompletion方法:该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。可以在方法中可以进行资源的释放操作。参数: * WebRequest:可以把我们在preHandle 中准备的资源传递到这里进行释放。 * Exception:表示的是当前请求的异常对象,如果在 Controller 中抛出的异常已经被 Spring 的异常处理器给处理了的话,那么这个异常对象就是是 null。 ### 在 SpringMVC 中使用 Interceptor ### 这里只介绍 XML 声明方式。 #### 使用 mvc:interceptors 标签 #### 方式一 : 直接定义一个 Interceptor 实现类的bean对象。使用这种方式声明的 Interceptor 拦截器将会对所有的请求进行拦截。 <mvc:interceptors> <bean class="com.my.FirstInterceptor"/> </mvc:interceptors> 方式二 : 使用 mvc:interceptor 标签进行声明。使用这种方式进行声明的 Interceptor 可以通过 mvc:mapping 子标签来定义需要进行拦截的请求路径。 <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/test/hello.do"/> <bean class="com.my.FirstInterceptor"/> </mvc:interceptor> </mvc:interceptors>
还没有评论,来说两句吧...