欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringMVC中使用Interceptor攔截器

 更新時(shí)間:2016年12月30日 14:53:35   作者:234390216  
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)前時(shí)間是否是購票時(shí)間。

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

SpringMVC 中的Interceptor 攔截請求是通過HandlerInterceptor 來實(shí)現(xiàn)的。在SpringMVC 中定義一個(gè)Interceptor 非常簡單,主要有兩種方式,第一種方式是要定義的Interceptor類要實(shí)現(xiàn)了Spring 的HandlerInterceptor 接口,或者是這個(gè)類繼承實(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 接口中定義了三個(gè)方法,我們就是通過這三個(gè)方法來對(duì)用戶的請求進(jìn)行攔截處理的。

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

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

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

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

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

下面是一個(gè)簡單的代碼說明:

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)降?,可以同時(shí)存在 
   * 多個(gè)Interceptor,然后SpringMVC會(huì)根據(jù)聲明的前后順序一個(gè)接一個(gè)的執(zhí)行,而且所有的Interceptor中的preHandle方法都會(huì)在 
   * Controller方法調(diào)用之前調(diào)用。SpringMVC的這種Interceptor鏈?zhǔn)浇Y(jié)構(gòu)也是可以進(jìn)行中斷的,這種中斷方式是令preHandle的返 
   * 回值為false,當(dāng)preHandle的返回值為false的時(shí)候整個(gè)請求就結(jié)束了。 
   */ 
  @Override 
  public boolean preHandle(HttpServletRequest request, 
      HttpServletResponse response, Object handler) throws Exception { 
    // TODO Auto-generated method stub 
    return false; 
  } 
   
  /** 
   * 這個(gè)方法只會(huì)在當(dāng)前這個(gè)Interceptor的preHandle方法返回值為true的時(shí)候才會(huì)執(zhí)行。postHandle是進(jìn)行處理器攔截用的,它的執(zhí)行時(shí)間是在處理器進(jìn)行處理之 
   * 后,也就是在Controller的方法調(diào)用之后執(zhí)行,但是它會(huì)在DispatcherServlet進(jìn)行視圖的渲染之前執(zhí)行,也就是說在這個(gè)方法中你可以對(duì)ModelAndView進(jìn)行操 
   * 作。這個(gè)方法的鏈?zhǔn)浇Y(jié)構(gòu)跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會(huì)后調(diào)用,這跟Struts2里面的攔截器的執(zhí)行過程有點(diǎn)像, 
   * 只是Struts2里面的intercept方法中要手動(dòng)的調(diào)用ActionInvocation的invoke方法,Struts2中調(diào)用ActionInvocation的invoke方法就是調(diào)用下一個(gè)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)前對(duì)應(yīng)的Interceptor的preHandle方法的返回值為true時(shí)才會(huì)執(zhí)行。該方法將在整個(gè)請求完成之后,也就是DispatcherServlet渲染了視圖執(zhí)行, 
   * 這個(gè)方法的主要作用是用于清理資源的,當(dāng)然這個(gè)方法也只能在當(dāng)前這個(gè)Interceptor的preHandle方法的返回值為true時(shí)才會(huì)執(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 中也定義了三個(gè)方法,我們也是通過這三個(gè)方法來實(shí)現(xiàn)攔截的。這三個(gè)方法都傳遞了同一個(gè)參數(shù)WebRequest ,那么這個(gè)WebRequest 是什么呢?這個(gè)WebRequest 是Spring 定義的一個(gè)接口,它里面的方法定義都基本跟HttpServletRequest 一樣,在WebRequestInterceptor 中對(duì)WebRequest 進(jìn)行的所有操作都將同步到HttpServletRequest 中,然后在當(dāng)前請求中一直傳遞。

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

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

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

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

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

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

下面是一個(gè)簡單的代碼說明:

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);//這個(gè)是放到request范圍內(nèi)的,所以只能在當(dāng)前請求中的request中獲取到 
    request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);//這個(gè)是放到session范圍內(nèi)的,如果環(huán)境允許的話它只能在局部的隔離的會(huì)話中訪問,否則就是在普通的當(dāng)前會(huì)話中可以訪問 
    request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);//如果環(huán)境允許的話,它能在全局共享的會(huì)話中訪問,否則就是在普通的當(dāng)前會(huì)話中訪問 
  } 
 
  /** 
   * 該方法將在Controller執(zhí)行之后,返回視圖之前執(zhí)行,ModelMap表示請求Controller處理之后返回的Model對(duì)象,所以可以在 
   * 這個(gè)方法中修改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"); 
  } 
 
  /** 
   * 該方法將在整個(gè)請求完成之后,也就是說在視圖渲染之后進(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

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" 

下面是我的聲明示例:

<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)簽中有一個(gè)mvc:interceptors是用于聲明SpringMVC的攔截器的。

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

<mvc:interceptors> 
  <!-- 使用bean定義一個(gè)Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 --> 
  <bean class="com.host.app.web.interceptor.AllInterceptor"/> 
  <mvc:interceptor> 
    <mvc:mapping path="/test/number.do"/> 
    <!-- 定義在mvc:interceptor下面的表示是對(duì)特定的請求才進(jìn)行攔截的 --> 
    <bean class="com.host.app.web.interceptor.LoginInterceptor"/> 
  </mvc:interceptor> 
</mvc:interceptors> 

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

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

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

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

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

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

相關(guān)文章

  • 詳解Servlet3.0新特性(從注解配置到websocket編程)

    詳解Servlet3.0新特性(從注解配置到websocket編程)

    Servlet3.0的出現(xiàn)是servlet史上最大的變革,其中的許多新特性大大的簡化了web應(yīng)用的開發(fā),為廣大勞苦的程序員減輕了壓力,提高了web開發(fā)的效率。
    2017-04-04
  • java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能詳解

    java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能詳解

    這篇文章主要介紹了java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能,結(jié)合實(shí)例形式詳細(xì)分析了Des加密算法的功能、原理、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-01-01
  • java實(shí)現(xiàn)消息隊(duì)列的兩種方式(小結(jié))

    java實(shí)現(xiàn)消息隊(duì)列的兩種方式(小結(jié))

    本文主要介紹了兩種java實(shí)現(xiàn)消息隊(duì)列的方式,利用Spring消息模板發(fā)送消息和Apache ActiveMQ官方實(shí)例發(fā)送消息,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Window搭建部署RocketMQ步驟詳解

    Window搭建部署RocketMQ步驟詳解

    這篇文章主要介紹了Window搭建部署RocketMQ步驟詳解,RocketMq是一個(gè)由阿里巴巴開源的消息中間件,脫胎去阿里每部使用的MetaQ,在設(shè)計(jì)上借鑒了Kafka。,需要的朋友可以參考下
    2019-06-06
  • java實(shí)現(xiàn)簡單網(wǎng)絡(luò)象棋游戲

    java實(shí)現(xiàn)簡單網(wǎng)絡(luò)象棋游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡單網(wǎng)絡(luò)象棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • SpringBoot自定義對(duì)象參數(shù)實(shí)現(xiàn)自動(dòng)類型轉(zhuǎn)換與格式化

    SpringBoot自定義對(duì)象參數(shù)實(shí)現(xiàn)自動(dòng)類型轉(zhuǎn)換與格式化

    SpringBoot 通過自定義對(duì)象參數(shù),可以實(shí)現(xiàn)自動(dòng)類型轉(zhuǎn)換與格式化,并可以級(jí)聯(lián)封裝,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析

    Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析

    這篇文章主要介紹了Mybatis-Plus多表關(guān)聯(lián)查詢的使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 最詳細(xì)的文件上傳下載實(shí)例詳解(推薦)

    最詳細(xì)的文件上傳下載實(shí)例詳解(推薦)

    在Web應(yīng)用系統(tǒng)開發(fā)中,文件上傳和下載功能是非常常用的功能,今天來講一下JavaWeb中的文件上傳和下載功能的實(shí)現(xiàn)。非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧
    2016-07-07
  • Java中如何比較兩個(gè)數(shù)組中元素是否相同

    Java中如何比較兩個(gè)數(shù)組中元素是否相同

    比較兩個(gè)數(shù)組中的元素是否相同,在項(xiàng)目中經(jīng)常會(huì)使用到,下面與大家分享個(gè)最簡單的方法
    2014-06-06
  • Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)多線程在線聊天

    Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)多線程在線聊天

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)多線程在線聊天,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論