程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> SpringMVC中攔截器的使用

SpringMVC中攔截器的使用

編輯:JAVA綜合教程

SpringMVC中攔截器的使用


SpringMVC中的Interceptor攔截器也是相當重要和相當有用的,它的主要作用是攔截用戶的請求並進行相應的處理。

比如通過它來進行權限驗證,或者是來判斷用戶是否登陸,或者是像12306那樣子判斷當前時間是否是購票時間。

一、定義Interceptor實現類

SpringMVC中的Interceptor攔截請求是通過HandlerInterceptor來實現的。在SpringMVC中定義一個Interceptor非常簡單,主要有兩種方式,第一種方式是要定義的Interceptor類要實現了Spring的HandlerInterceptor接口,或者是這個類繼承實現了HandlerInterceptor接口的類,比如Spring已經提供的實現了HandlerInterceptor接口的抽象類HandlerInterceptorAdapter;第二種方式是實現Spring的WebRequestInterceptor接口,或者是繼承實現了WebRequestInterceptor的類。

(一)實現HandlerInterceptor接口

HandlerInterceptor接口中定義了三個方法,我們就是通過這三個方法來對用戶的請求進行攔截處理的。

(1)preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顧名思義,該方法將在請求處理之前進行調用。SpringMVC中的Interceptor是鏈式的調用的,在一個應用中或者說是在一個請求中可以同時存在多個Interceptor。每個Interceptor的調用會依據它的聲明順序依次執行,而且最先執行的都是Interceptor中的preHandle方法,所以可以在這個方法中進行一些前置初始化操作或者是對當前請求的一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布爾值Boolean類型的,當它返回為false時,表示請求結束,後續的Interceptor和Controller都不會再執行;當返回值為true時就會繼續調用下一個Interceptor的preHandle方法,如果已經是最後一個Interceptor的時候就會是調用當前請求的Controller方法。

(2)postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle方法的解釋我們知道這個方法包括後面要說到的afterCompletion方法都只能是在當前所屬的Interceptor的preHandle方法的返回值為true時才能被調用。postHandle方法,顧名思義就是在當前請求進行處理之後,也就是Controller方法調用之後執行,但是它會在DispatcherServlet進行視圖返回渲染之前被調用,所以我們可以在這個方法中對Controller處理之後的ModelAndView對象進行操作。postHandle方法被調用的方向跟preHandle是相反的,也就是說先聲明的Interceptor的postHandle方法反而會後執行,這和Struts2裡面的Interceptor的執行過程有點類型。Struts2裡面的Interceptor的執行過程也是鏈式的,只是在Struts2裡面需要手動調用ActionInvocation的invoke方法來觸發對下一個Interceptor或者是Action的調用,然後每一個Interceptor中在invoke方法調用之前的內容都是按照聲明順序執行的,而invoke方法之後的內容就是反向的。

(3)afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行。顧名思義,該方法將在整個請求結束之後,也就是在DispatcherServlet渲染了對應的視圖之後執行。這個方法的主要作用是用於進行資源清理工作的。

下面是一個簡單的代碼說明:

Java代碼收藏代碼
  1. importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.springframework.web.servlet.HandlerInterceptor;importorg.springframework.web.servlet.ModelAndView;publicclassSpringMVCInterceptorimplementsHandlerInterceptor{/***preHandle方法是進行處理器攔截用的,顧名思義,該方法將在Controller處理之前進行調用,SpringMVC中的Interceptor攔截器是鏈式的,可以同時存在*多個Interceptor,然後SpringMVC會根據聲明的前後順序一個接一個的執行,而且所有的Interceptor中的preHandle方法都會在*Controller方法調用之前調用。SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,這種中斷方式是令preHandle的返*回值為false,當preHandle的返回值為false的時候整個請求就結束了。*/@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{//TODOAuto-generatedmethodstubreturnfalse;}/***這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執行。postHandle是進行處理器攔截用的,它的執行時間是在處理器進行處理之*後,也就是在Controller的方法調用之後執行,但是它會在DispatcherServlet進行視圖的渲染之前執行,也就是說在這個方法中你可以對ModelAndView進行操*作。這個方法的鏈式結構跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會後調用,這跟Struts2裡面的攔截器的執行過程有點像,*只是Struts2裡面的intercept方法中要手動的調用ActionInvocation的invoke方法,Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor*或者是調用action,然後要在Interceptor之前調用的內容都寫在調用invoke之前,要在Interceptor之後調用的內容都寫在調用invoke方法之後。*/@OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{//TODOAuto-generatedmethodstub}/***該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行。該方法將在整個請求完成之後,也就是DispatcherServlet渲染了視圖執行,*這個方法的主要作用是用於清理資源的,當然這個方法也只能在當前這個Interceptor的preHandle方法的返回值為true時才會執行。*/@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{//TODOAuto-generatedmethodstub}}

(二)實現WebRequestInterceptor接口

WebRequestInterceptor中也定義了三個方法,我們也是通過這三個方法來實現攔截的。這三個方法都傳遞了同一個參數WebRequest,那麼這個WebRequest是什麼呢?這個WebRequest是Spring定義的一個接口,它裡面的方法定義都基本跟HttpServletRequest一樣,在WebRequestInterceptor中對WebRequest進行的所有操作都將同步到HttpServletRequest中,然後在當前請求中一直傳遞。

(1)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范圍內可以訪問。

(2)postHandle(WebRequest request, ModelMap model)方法。該方法將在請求處理之後,也就是在Controller方法調用之後被調用,但是會在視圖返回被渲染之前被調用,所以可以在這個方法裡面通過改變數據模型ModelMap來改變數據的展示。該方法有兩個參數,WebRequest對象是用於傳遞整個請求數據的,比如在preHandle中准備的數據都可以通過WebRequest來傳遞和訪問;ModelMap就是Controller處理之後返回的Model對象,我們可以通過改變它的屬性來改變返回的Model模型。

(3)afterCompletion(WebRequest request, Exception ex)方法。該方法會在整個請求處理完成,也就是在視圖返回並被渲染之後執行。所以在該方法中可以進行資源的釋放操作。而WebRequest參數就可以把我們在preHandle中准備的資源傳遞到這裡進行釋放。Exception參數表示的是當前請求的異常對象,如果在Controller中拋出的異常已經被Spring的異常處理器給處理了的話,那麼這個異常對象就是是null。

下面是一個簡單的代碼說明:

Java代碼收藏代碼
  1. importorg.springframework.ui.ModelMap;importorg.springframework.web.context.request.WebRequest;importorg.springframework.web.context.request.WebRequestInterceptor;publicclassAllInterceptorimplementsWebRequestInterceptor{/***在請求處理之前執行,該方法主要是用於准備資源數據的,然後可以把它們當做請求屬性放到WebRequest中*/@OverridepublicvoidpreHandle(WebRequestrequest)throwsException{//TODOAuto-generatedmethodstubSystem.out.println("AllInterceptor...............................");request.setAttribute("request","request",WebRequest.SCOPE_REQUEST);//這個是放到request范圍內的,所以只能在當前請求中的request中獲取到request.setAttribute("session","session",WebRequest.SCOPE_SESSION);//這個是放到session范圍內的,如果環境允許的話它只能在局部的隔離的會話中訪問,否則就是在普通的當前會話中可以訪問request.setAttribute("globalSession","globalSession",WebRequest.SCOPE_GLOBAL_SESSION);//如果環境允許的話,它能在全局共享的會話中訪問,否則就是在普通的當前會話中訪問}/***該方法將在Controller執行之後,返回視圖之前執行,ModelMap表示請求Controller處理之後返回的Model對象,所以可以在*這個方法中修改ModelMap的屬性,從而達到改變返回的模型的效果。*/@OverridepublicvoidpostHandle(WebRequestrequest,ModelMapmap)throwsException{//TODOAuto-generatedmethodstubfor(Stringkey:map.keySet())System.out.println(key+"-------------------------");;map.put("name3","value3");map.put("name1","name1");}/***該方法將在整個請求完成之後,也就是說在視圖渲染之後進行調用,主要用於進行一些資源的釋放*/@OverridepublicvoidafterCompletion(WebRequestrequest,Exceptionexception)throwsException{//TODOAuto-generatedmethodstubSystem.out.println(exception+"-=-=--=--=-=-=-=-=-=-=-=-==-=--=-=-=-=");}}

二、把定義的攔截器類加到SpringMVC的攔截體系中

1.在SpringMVC的配置文件中加上支持MVC的schema

Xml代碼收藏代碼
  1. xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"

下面是我的聲明示例:

Xml代碼收藏代碼

    這樣在SpringMVC的配置文件中就可以使用mvc標簽了,mvc標簽中有一個mvc:interceptors是用於聲明SpringMVC的攔截器的。

    (二)使用mvc:interceptors標簽來聲明需要加入到SpringMVC攔截器鏈中的攔截器

    Xml代碼收藏代碼

    由上面的示例可以看出可以利用mvc:interceptors標簽聲明一系列的攔截器,然後它們就可以形成一個攔截器鏈,攔截器的執行順序是按聲明的先後順序執行的,先聲明的攔截器中的preHandle方法會先執行,然而它的postHandle方法和afterCompletion方法卻會後執行。

    在mvc:interceptors標簽下聲明interceptor主要有兩種方式:

    (1)直接定義一個Interceptor實現類的bean對象。使用這種方式聲明的Interceptor攔截器將會對所有的請求進行攔截。

    (2)使用mvc:interceptor標簽進行聲明。使用這種方式進行聲明的Interceptor可以通過mvc:mapping子標簽來定義需要進行攔截的請求路徑。

    經過上述兩步之後,定義的攔截器就會發生作用對特定的請求進行攔截了。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved