Spring總結之SpringMvc下
阿新 • • 發佈:2019-05-08
register edi exc 共享 tin 結構 ram session post
五、攔截器
SpringMVC中的攔截器是通過HandlerInterceptor來實現的,定義一個Interceptor有兩種方式
1、實現HandlerInterceptor接口或者繼承實現了HandlerInterceptor接口的類,例如抽象類HandlerInterceptorAdapter
HandlerInterceptor 接口中定義了三個方法,我們就是通過這三個方法來對用戶的請求進行攔截處理的。
public class SpringMVCInterceptor implements HandlerInterceptor{ /** * preHandle方法是進行處理器攔截用的,顧名思義,該方法將在Controller處理之前進行調用,SpringMVC中的Interceptor攔截器是鏈式的,可以同時存在 * 多個Interceptor,然後SpringMVC會根據聲明的前後順序一個接一個的執行,而且所有的Interceptor中的preHandle方法都會在Controller方法調用之前調用。 * SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,這種中斷方式是令preHandle的返 回值為false, * 當preHandle的返回值為false的時候整個請求就結束了。*/ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; } /** * 這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執行。 * postHandle是進行處理器攔截用的,它的執行時間是在處理器進行處理之 後,也就是在Controller的方法調用之後執行, * 但是它會在DispatcherServlet進行視圖的渲染之前執行,也就是說在這個方法中你可以對ModelAndView進行操 作。 * 這個方法的鏈式結構跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會後調用.*/ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行。 * 該方法將在整個請求完成之後,也就是DispatcherServlet渲染了視圖執行, * 這個方法的主要作用是用於清理資源的,當然這個方法也只能在當前這個Interceptor的preHandle方法的返回值為true時才會執行。*/ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
2、實現WebRequestInterceptor接口或這繼承實現了WebRequestInterceptor接口的類。
WebRequestInterceptor 中也定義了三個方法,我們也是通過這三個方法來實現攔截的。這三個方法都傳遞了同一個參數WebRequest ,WebRequest 是Spring 定義的一個接口,它裏面的方法定義都基本跟HttpServletRequest 一樣,在WebRequestInterceptor 中對WebRequest 進行的所有操作都將同步到HttpServletRequest 中,然後在當前請求中一直傳遞。
public class SpringMVCInterceptor2 implements WebRequestInterceptor{ /** * preHandle(WebRequest request) 方法。該方法將在請求處理之前進行調用,也就是說會在Controller 方法調用之前被調用。 * 這個方法跟HandlerInterceptor 中的preHandle 是不同的,主要區別在於該方法的返回值是void ,也就是沒有返回值, * 所以我們一般主要用它來進行資源的準備工作,比如我們在使用Hibernate 的時候可以在這個方法中準備一個Hibernate 的Session 對象, * 然後利用WebRequest 的setAttribute(name, value, scope)把它放到WebRequest 的屬性中。 * 這裏可以說說這個setAttribute 方法的第三個參數scope ,該參數是一個Integer類型的。在WebRequest 的父層接口RequestAttributes 中對它定義了三個常量: * SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以訪問。 * SCOPE_SESSION :它的值是1 ,如果環境允許的話它代表的是一個局部的隔離的session,否則就代表普通的session,並且在該session範圍內可以訪問。 * SCOPE_GLOBAL_SESSION :它的值是2 ,如果環境允許的話,它代表的是一個全局共享的session,否則就代表普通的session,並且在該session 範圍內可以訪問。 * */ public void preHandle(WebRequest request) throws Exception { System.out.println("AllInterceptor..............................."); request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST); request.setAttribute("session", "session", WebRequest.SCOPE_SESSION); request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION); } /** * postHandle(WebRequest request, ModelMap model) 方法。該方法將在請求處理之後,也就是在Controller 方法調用之後被調用, * 但是會在視圖返回被渲染之前被調用,所以可以在這個方法裏面通過改變數據模型ModelMap 來改變數據的展示。 * 該方法有兩個參數,WebRequest 對象是用於傳遞整個請求數據的,比如在preHandle 中準備的數據都可以通過WebRequest 來傳遞和訪問; * ModelMap 就是Controller 處理之後返回的Model 對象,我們可以通過改變它的屬性來改變返回的Model 模型 */ public void postHandle(WebRequest request, ModelMap model) throws Exception { } /** * 該方法將在整個請求完成之後,也就是說在視圖渲染之後進行調用,主要用於進行一些資源的釋放 */ public void afterCompletion(WebRequest request, Exception ex) throws Exception { } }
<mvc:interceptors> <!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 --> <bean class="com.host.app.web.interceptor.AllInterceptor"/> <mvc:interceptor> <mvc:mapping path="/test/number.do"/> <!-- 定義在mvc:interceptor下面的表示是對特定的請求才進行攔截的 --> <bean class="com.host.app.web.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
六、亂碼問題
<mvc:annotation-driven >
<mvc:message-converters register-defaults="true">
<!-- 解決@ResponseBody中文亂碼 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Spring總結之SpringMvc下