一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解SpringMVC中使用Interceptor攔截器

詳解SpringMVC中使用Interceptor攔截器

2020-07-20 13:34234390216 Java教程

SpringMVC 中的Interceptor 攔截器也是相當(dāng)重要和相當(dāng)有用的,它的主要作用是攔截用戶的請求并進(jìn)行相應(yīng)的處理,這篇文章主要介紹了詳解SpringMVC中使用Interceptor攔截器,有興趣的可以了解一下。

SpringMVC 中的Interceptor 攔截器也是相當(dāng)重要和相當(dāng)有用的,它的主要作用是攔截用戶的請求并進(jìn)行相應(yīng)的處理。比如通過它來進(jìn)行權(quán)限驗(yàn)證,或者是來判斷用戶是否登陸,或者是像12306 那樣子判斷當(dāng)前時間是否是購票時間。

 一、定義Interceptor實(shí)現(xiàn)類

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

(一)實(shí)現(xiàn)HandlerInterceptor接口

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

(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顧名思義,該方法將在請求處理之前進(jìn)行調(diào)用。SpringMVC 中的Interceptor 是鏈?zhǔn)降恼{(diào)用的,在一個應(yīng)用中或者說是在一個請求中可以同時存在多個Interceptor 。每個Interceptor 的調(diào)用會依據(jù)它的聲明順序依次執(zhí)行,而且最先執(zhí)行的都是Interceptor 中的preHandle 方法,所以可以在這個方法中進(jìn)行一些前置初始化操作或者是對當(dāng)前請求的一個預(yù)處理,也可以在這個方法中進(jìn)行一些判斷來決定請求是否要繼續(xù)進(jìn)行下去。

該方法的返回值是布爾值Boolean 類型的,當(dāng)它返回為false 時,表示請求結(jié)束,后續(xù)的Interceptor 和Controller 都不會再執(zhí)行;當(dāng)返回值為true 時就會繼續(xù)調(diào)用下一個Interceptor 的preHandle 方法,如果已經(jīng)是最后一個Interceptor 的時候就會是調(diào)用當(dāng)前請求的Controller 方法。

(2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解釋我們知道這個方法包括后面要說到的afterCompletion 方法都只能是在當(dāng)前所屬的Interceptor 的preHandle 方法的返回值為true 時才能被調(diào)用。

postHandle 方法,顧名思義就是在當(dāng)前請求進(jìn)行處理之后,也就是Controller 方法調(diào)用之后執(zhí)行,但是它會在DispatcherServlet 進(jìn)行視圖返回渲染之前被調(diào)用,所以我們可以在這個方法中對Controller 處理之后的ModelAndView 對象進(jìn)行操作。postHandle 方法被調(diào)用的方向跟preHandle 是相反的,也就是說先聲明的Interceptor 的postHandle 方法反而會后執(zhí)行,這和Struts2 里面的Interceptor 的執(zhí)行過程有點(diǎn)類型。Struts2 里面的Interceptor 的執(zhí)行過程也是鏈?zhǔn)降模皇窃赟truts2 里面需要手動調(diào)用ActionInvocation 的invoke 方法來觸發(fā)對下一個Interceptor 或者是Action 的調(diào)用,然后每一個Interceptor 中在invoke 方法調(diào)用之前的內(nèi)容都是按照聲明順序執(zhí)行的,而invoke 方法之后的內(nèi)容就是反向的。

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
public class SpringMVCInterceptor implements HandlerInterceptor {
 
 
  /**
   * preHandle方法是進(jìn)行處理器攔截用的,顧名思義,該方法將在Controller處理之前進(jìn)行調(diào)用,SpringMVC中的Interceptor攔截器是鏈?zhǔn)降模梢酝瑫r存在
   * 多個Interceptor,然后SpringMVC會根據(jù)聲明的前后順序一個接一個的執(zhí)行,而且所有的Interceptor中的preHandle方法都會在
   * Controller方法調(diào)用之前調(diào)用。SpringMVC的這種Interceptor鏈?zhǔn)浇Y(jié)構(gòu)也是可以進(jìn)行中斷的,這種中斷方式是令preHandle的返
   * 回值為false,當(dāng)preHandle的返回值為false的時候整個請求就結(jié)束了。
   */
  @Override
  public boolean preHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler) throws Exception {
    // TODO Auto-generated method stub
    return false;
  }
   
  /**
   * 這個方法只會在當(dāng)前這個Interceptor的preHandle方法返回值為true的時候才會執(zhí)行。postHandle是進(jìn)行處理器攔截用的,它的執(zhí)行時間是在處理器進(jìn)行處理之
   * 后,也就是在Controller的方法調(diào)用之后執(zhí)行,但是它會在DispatcherServlet進(jìn)行視圖的渲染之前執(zhí)行,也就是說在這個方法中你可以對ModelAndView進(jìn)行操
   * 作。這個方法的鏈?zhǔn)浇Y(jié)構(gòu)跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會后調(diào)用,這跟Struts2里面的攔截器的執(zhí)行過程有點(diǎn)像,
   * 只是Struts2里面的intercept方法中要手動的調(diào)用ActionInvocation的invoke方法,Struts2中調(diào)用ActionInvocation的invoke方法就是調(diào)用下一個Interceptor
   * 或者是調(diào)用action,然后要在Interceptor之前調(diào)用的內(nèi)容都寫在調(diào)用invoke之前,要在Interceptor之后調(diào)用的內(nèi)容都寫在調(diào)用invoke方法之后。
   */
  @Override
  public void postHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler,
      ModelAndView modelAndView) throws Exception {
    // TODO Auto-generated method stub
     
  }
 
  /**
   * 該方法也是需要當(dāng)前對應(yīng)的Interceptor的preHandle方法的返回值為true時才會執(zhí)行。該方法將在整個請求完成之后,也就是DispatcherServlet渲染了視圖執(zhí)行,
   * 這個方法的主要作用是用于清理資源的,當(dāng)然這個方法也只能在當(dāng)前這個Interceptor的preHandle方法的返回值為true時才會執(zhí)行。
   */
  @Override
  public void afterCompletion(HttpServletRequest request,
      HttpServletResponse response, Object handler, Exception ex)
  throws Exception {
    // TODO Auto-generated method stub
     
  }
   
}

(二)實(shí)現(xiàn)WebRequestInterceptor 接口

WebRequestInterceptor 中也定義了三個方法,我們也是通過這三個方法來實(shí)現(xiàn)攔截的。這三個方法都傳遞了同一個參數(shù)WebRequest ,那么這個WebRequest 是什么呢?這個WebRequest 是Spring 定義的一個接口,它里面的方法定義都基本跟HttpServletRequest 一樣,在WebRequestInterceptor 中對WebRequest 進(jìn)行的所有操作都將同步到HttpServletRequest 中,然后在當(dāng)前請求中一直傳遞。

(1 )preHandle(WebRequest request) 方法。該方法將在請求處理之前進(jìn)行調(diào)用,也就是說會在Controller 方法調(diào)用之前被調(diào)用。這個方法跟HandlerInterceptor 中的preHandle 是不同的,主要區(qū)別在于該方法的返回值是void ,也就是沒有返回值,所以我們一般主要用它來進(jìn)行資源的準(zhǔn)備工作,比如我們在使用Hibernate 的時候可以在這個方法中準(zhǔn)備一個Hibernate 的Session 對象,然后利用WebRequest 的setAttribute(name, value, scope) 把它放到WebRequest 的屬性中。這里可以說說這個setAttribute 方法的第三個參數(shù)scope ,該參數(shù)是一個Integer 類型的。在WebRequest 的父層接口RequestAttributes 中對它定義了三個常量:

SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以訪問。

SCOPE_SESSION :它的值是1 ,如果環(huán)境允許的話它代表的是一個局部的隔離的session,否則就代表普通的session,并且在該session范圍內(nèi)可以訪問。

SCOPE_GLOBAL_SESSION :它的值是2 ,如果環(huán)境允許的話,它代表的是一個全局共享的session,否則就代表普通的session,并且在該session 范圍內(nèi)可以訪問。

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

(3 )afterCompletion(WebRequest request, Exception ex) 方法。該方法會在整個請求處理完成,也就是在視圖返回并被渲染之后執(zhí)行。所以在該方法中可以進(jìn)行資源的釋放操作。而WebRequest 參數(shù)就可以把我們在preHandle 中準(zhǔn)備的資源傳遞到這里進(jìn)行釋放。Exception 參數(shù)表示的是當(dāng)前請求的異常對象,如果在Controller 中拋出的異常已經(jīng)被Spring 的異常處理器給處理了的話,那么這個異常對象就是是null 。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
 
public class AllInterceptor implements WebRequestInterceptor {
   
  /**
   * 在請求處理之前執(zhí)行,該方法主要是用于準(zhǔn)備資源數(shù)據(jù)的,然后可以把它們當(dāng)做請求屬性放到WebRequest中
   */
  @Override
  public void preHandle(WebRequest request) throws Exception {
    // TODO Auto-generated method stub
    System.out.println("AllInterceptor...............................");
    request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST);//這個是放到request范圍內(nèi)的,所以只能在當(dāng)前請求中的request中獲取到
    request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);//這個是放到session范圍內(nèi)的,如果環(huán)境允許的話它只能在局部的隔離的會話中訪問,否則就是在普通的當(dāng)前會話中可以訪問
    request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);//如果環(huán)境允許的話,它能在全局共享的會話中訪問,否則就是在普通的當(dāng)前會話中訪問
  }
 
  /**
   * 該方法將在Controller執(zhí)行之后,返回視圖之前執(zhí)行,ModelMap表示請求Controller處理之后返回的Model對象,所以可以在
   * 這個方法中修改ModelMap的屬性,從而達(dá)到改變返回的模型的效果。
   */
  @Override
  public void postHandle(WebRequest request, ModelMap map) throws Exception {
    // TODO Auto-generated method stub
    for (String key:map.keySet())
      System.out.println(key + "-------------------------");;
    map.put("name3", "value3");
    map.put("name1", "name1");
  }
 
  /**
   * 該方法將在整個請求完成之后,也就是說在視圖渲染之后進(jìn)行調(diào)用,主要用于進(jìn)行一些資源的釋放
   */
  @Override
  public void afterCompletion(WebRequest request, Exception exception)
  throws Exception {
    // TODO Auto-generated method stub
    System.out.println(exception + "-=-=--=--=-=-=-=-=-=-=-=-==-=--=-=-=-=");
  }
   
}

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

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

?
1
2
3
xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation=" http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"

下面是我的聲明示例:

?
1
2
3
4
5
6
7
8
9
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

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

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

?
1
2
3
4
5
6
7
8
9
<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下面的表示是對特定的請求才進(jìn)行攔截的 -->
    <bean class="com.host.app.web.interceptor.LoginInterceptor"/>
  </mvc:interceptor>
</mvc:interceptors>

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

在mvc:interceptors標(biāo)簽下聲明interceptor主要有兩種方式:

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

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

經(jīng)過上述兩步之后,定義的攔截器就會發(fā)生作用對特定的請求進(jìn)行攔截了。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://elim.iteye.com/blog/1750680

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品99一区二区三区麻豆 | 欧美精品成人a多人在线观看 | 201天天爱天天做 | 韩国最新理论片奇忧影院 | 久久久乱码精品亚洲日韩 | 精品午夜视频 | 日本加勒比在线播放 | 91人成网站色www | 污软件在线观看 | 白丝尤物的下面被疯狂蹂躏 | 亚洲国产精品第一页 | 亚洲精品在线免费 | 国产成人91高清精品免费 | 亚洲精品高清中文字幕完整版 | 国产精品免费观在线 | 亚洲毛片基地4455ww | 欧美图片小说 | 99久久精品无码一区二区毛片 | 粉嫩极品国产在线观看免费 | 男人天堂视频网 | 日本精品一区二区三区 | 青柠在线完整高清观看免费 | 全彩成人18h漫画 | 国产肥老上视频 | 四虎www| 爸爸干女儿小说 | 国产一卡2卡3卡四卡高清 | 日本一道一区二区免费看 | 欧美大片一级片 | 女同全黄h全肉动漫 | 国产欧美日韩精品一区二区三区 | 国产美女亚洲精品久久久久久 | 亚洲免费视频在线观看 | 精品国产线拍大陆久久尤物 | free性日本 | 久久精品男人影院 | 小妇人电影免费完整观看2021 | 国内精品91东航翘臀女神在线 | 满城尽带黄金甲大胸片 | 丁香成人社| 亚洲国产精品无码中文字幕 |