Java web攔截器inteceptor原理及應(yīng)用詳解
這篇文章主要介紹了java web攔截器inteceptor原理及應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
一、簡(jiǎn)介
java里的攔截器提供的是非系統(tǒng)級(jí)別的攔截,也就是說,就覆蓋面來說,攔截器不如過濾器強(qiáng)大,但是更有針對(duì)性。
Java中的攔截器是基于Java反射機(jī)制實(shí)現(xiàn)的,更準(zhǔn)確的劃分,應(yīng)該是基于JDK實(shí)現(xiàn)的動(dòng)態(tài)代理。它依賴于具體的接口,在運(yùn)行期間動(dòng)態(tài)生成字節(jié)碼。
攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象,它提供了一種機(jī)制可以使開發(fā)者在一個(gè)Action執(zhí)行的前后執(zhí)行一段代碼,也可以在一個(gè)Action執(zhí)行前阻止其執(zhí)行,同時(shí)也提供了一種可以提取Action中可重用部分代碼的方式。在AOP中,攔截器用于在某個(gè)方法或者字段被訪問之前,進(jìn)行攔截然后再之前或者之后加入某些操作。java的攔截器主要是用在插件上,擴(kuò)展件上比如 Hibernate Spring Struts2等,有點(diǎn)類似面向切片的技術(shù),在用之前先要在配置文件即xml,文件里聲明一段的那個(gè)東西。
SpringMVC 中的Interceptor 攔截器的主要作用就是攔截用戶的 url 請(qǐng)求,并在執(zhí)行 handler 方法的前中后加入某些特殊請(qǐng)求,類似于 servlet 里面的過濾器.
SpringMVC 中的Interceptor 攔截器也是相當(dāng)重要和相當(dāng)有用的,它的主要作用是攔截用戶的請(qǐng)求并進(jìn)行相應(yīng)的處理。比如通過它來進(jìn)行權(quán)限驗(yàn)證,或者是來判斷用戶是否登陸,或者是像12306 那樣子判斷當(dāng)前時(shí)間是否是購(gòu)票時(shí)間。
二、應(yīng)用場(chǎng)景
1、日志記錄,可以記錄請(qǐng)求信息的日志,以便進(jìn)行信息監(jiān)控、信息統(tǒng)計(jì)等。
2、權(quán)限檢查:如登陸檢測(cè),進(jìn)入處理器檢測(cè)是否登陸,如果沒有直接返回到登陸頁面。
3、性能監(jiān)控:典型的是慢日志。
三、實(shí)現(xiàn)
3.1 實(shí)現(xiàn)方式
SpringMVC 中的Interceptor 攔截請(qǐng)求是通過HandlerInterceptor 來實(shí)現(xiàn)的。在SpringMVC 中定義一個(gè)Interceptor 非常簡(jiǎn)單,主要有兩種方式,
方式一:
定義的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接口詳細(xì)說明:
HandlerInterceptor 接口中定義了三個(gè)方法,我們就是通過這三個(gè)方法來對(duì)用戶的請(qǐng)求進(jìn)行攔截處理的。
(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顧名思義,該方法將在請(qǐng)求處理之前進(jìn)行調(diào)用。SpringMVC 中的Interceptor 是鏈?zhǔn)降恼{(diào)用的,在一個(gè)應(yīng)用中或者說是在一個(gè)請(qǐng)求中可以同時(shí)存在多個(gè)Interceptor 。每個(gè)Interceptor 的調(diào)用會(huì)依據(jù)它的聲明順序依次執(zhí)行,而且最先執(zhí)行的都是Interceptor 中的preHandle 方法,所以可以在這個(gè)方法中進(jìn)行一些前置初始化操作或者是對(duì)當(dāng)前請(qǐng)求的一個(gè)預(yù)處理,也可以在這個(gè)方法中進(jìn)行一些判斷來決定請(qǐng)求是否要繼續(xù)進(jìn)行下去。該方法的返回值是布爾值Boolean 類型的,當(dāng)它返回為false 時(shí),表示請(qǐng)求結(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)前請(qǐ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)前請(qǐ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)降?,只是在Struts2 里面需要手動(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è)請(qǐng)求結(jié)束之后,也就是在DispatcherServlet 渲染了對(duì)應(yīng)的視圖之后執(zhí)行。這個(gè)方法的主要作用是用于進(jìn)行資源清理工作的。
3.2 實(shí)現(xiàn)示例
直接上代碼:
3.2.1 自定義攔截器類
package com.my.dm.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class TestInterceptor implements HandlerInterceptor { private Logger logger =LogManager.getLogger(TestInterceptor.class); @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub logger.error("afterCompletion"); } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub logger.error("postHandle"); } @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { // TODO Auto-generated method stub logger.error("preHandle"); return true; } }
3.2.2 對(duì)應(yīng)單個(gè)攔截器配置
<!-- 配置攔截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.my.dm.interceptor.TestInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
3.2.3 對(duì)多個(gè)攔截器配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/employee/**" /> <mvc:mapping path="/trainning/**" /> <mvc:mapping path="/manage/**" /> <mvc:exclude-mapping path="/**/fonts/*" /> <mvc:exclude-mapping path="/**/*.css" /> <mvc:exclude-mapping path="/**/*.js" /> <mvc:exclude-mapping path="/**/*.png" /> <mvc:exclude-mapping path="/**/*.gif" /> <mvc:exclude-mapping path="/**/*.jpg" /> <mvc:exclude-mapping path="/**/*.jpeg" /> <bean class="com.pmo.interceptor.PageInterceptor" /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.pmo.interceptor.LoginInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.pmo.interceptor.UserAuthorityInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:簡(jiǎn)單了解Mybatis如何實(shí)現(xiàn)SQL防注入
欄 目:Java
下一篇:java ArrayList.remove()的三種錯(cuò)誤用法以及六種正確用法詳解
本文標(biāo)題:Java web攔截器inteceptor原理及應(yīng)用詳解
本文地址:http://mengdiqiu.com.cn/a1/Java/8734.html
您可能感興趣的文章
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10淺談Java中真的只有值傳遞么
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問題


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10Springboot中@Value的使用詳解
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10淺談Java中真的只有值傳遞么
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?