最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何處理器攔截器(HandlerInterceptor)

 更新時間:2023年07月10日 08:48:25   作者:編程界的小學生  
這篇文章主要介紹了如何處理器攔截器(HandlerInterceptor)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

簡介

SpringWebMVC的處理器攔截器,類似于Servlet開發(fā)中的過濾器Filter,用于處理器進行預處理和后處理。

應用場景

1、日志記錄,可以記錄請求信息的日志,以便進行信息監(jiān)控、信息統(tǒng)計等。

2、權限檢查:如登陸檢測,進入處理器檢測是否登陸,如果沒有直接返回到登陸頁面。

3、性能監(jiān)控:典型的是慢日志。

HandlerInterceptor

public interface HandlerInterceptor {
? ?/**
? ? ?* 預處理回調方法,實現(xiàn)處理器的預處理(如檢查登陸),第三個參數(shù)為響應的處理器,自定義Controller
? ? ?* 返回值:true表示繼續(xù)流程(如調用下一個攔截器或處理器);false表示流程中斷
(如登錄檢查失?。粫^續(xù)調用其他的攔截器或處理器,此時我們需要通過response來產生響應;
? ?*/
? ? boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception;
? ?/**
? ? ?* 后處理回調方法,實現(xiàn)處理器的后處理(但在渲染視圖之前),此時我們可以
通過modelAndView(模型和視圖對象)對模型數(shù)據(jù)進行處理或對視圖進行處理,modelAndView也可能為null。
? ?*/
? ? void postHandle(
? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
? ? ? ? ? ? throws Exception;
? ?/**
? ? * 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監(jiān)控中我們可以在此記錄結束時間并輸出消耗時間,還可以進行一些資源清理,類似于try-catch-finally中的finally,但僅調用處理器執(zhí)行鏈中
? ?*/
? ? void afterCompletion(
? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
? ? ? ? ? ? throws Exception;
}

攔截器適配器HandlerInterceptorAdapter

有時候我們可能只需要實現(xiàn)三個回調方法中的某一個,如果實現(xiàn)HandlerInterceptor接口的話,三個方法必須實現(xiàn),不管你需不需要,此時spring提供了一個HandlerInterceptorAdapter適配器(種適配器設計模式的實現(xiàn)),允許我們只實現(xiàn)需要的回調方法。

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
? ? /**
? ? ?* 默認是true
? ? ?*/
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception {
? ? ? ? return true;
? ? }
? ? /**
? ? ?* This implementation is empty.
? ? ?*/
? ? @Override
? ? public void postHandle(
? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
? ? ? ? ? ? throws Exception {
? ? }
? ? /**
? ? ?* This implementation is empty.
? ? ?*/
? ? @Override
? ? public void afterCompletion(
? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
? ? ? ? ? ? throws Exception {
? ? }
? ? /**
? ? ?* 不是HandlerInterceptor的接口實現(xiàn),是AsyncHandlerInterceptor的,AsyncHandlerInterceptor實現(xiàn)了HandlerInterceptor
? ? ?*/
? ? @Override
? ? public void afterConcurrentHandlingStarted(
? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception {
? ? }
}

這樣在我們業(yè)務中比如要記錄系統(tǒng)日志,日志肯定是在afterCompletion之后記錄的,否則中途失敗了,也記錄了,那就扯淡了。

一定是程序正常跑完后,我們記錄下那些對數(shù)據(jù)庫做個增刪改的操作日志進數(shù)據(jù)庫。

所以我們只需要繼承HandlerInterceptorAdapter,并重寫afterCompletion一個方法即可,因為preHandle默認是true。

運行流程總結如下

1、攔截器執(zhí)行順序是按照Spring配置文件中定義的順序而定的。

2、會先按照順序執(zhí)行所有攔截器的preHandle方法,一直遇到return false為止,比如第二個preHandle方法是return false,則第三個以及以后所有攔截器都不會執(zhí)行。若都是return true,則按順序加載完preHandle方法。

3、然后執(zhí)行主方法(自己的controller接口),若中間拋出異常,則跟return false效果一致,不會繼續(xù)執(zhí)行postHandle,只會倒序執(zhí)行afterCompletion方法。

4、在主方法執(zhí)行完業(yè)務邏輯(頁面還未渲染數(shù)據(jù))時,按倒序執(zhí)行postHandle方法。若第三個攔截器的postHandle方法return false,則會執(zhí)行第二個和第一個的postHandle方法和afterCompletion(postHandle都執(zhí)行完才會執(zhí)行這個,也就是頁面渲染完數(shù)據(jù)后,執(zhí)行after進行清理工作)方法。(postHandle和afterCompletion都是倒序執(zhí)行)

正常流程Demo

package com.bshf.recipe.demo.syslog;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SyslogInterceptor implements HandlerInterceptor {
? ? /**
? ? ?* 預處理回調方法,實現(xiàn)處理器的預處理(如檢查登陸),第三個參數(shù)為響應的處理器,自定義Controller
? ? ?* 返回值:true表示繼續(xù)流程(如調用下一個攔截器或處理器);false表示流程中斷(如登錄檢查失?。粫^續(xù)調用其他的攔截器或處理器,此時我們需要通過response來產生響應;
? ? ?*/
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================1================================================");
? ? ? ? return true;
? ? }
? ? /**
? ? ?* 后處理回調方法,實現(xiàn)處理器的后處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數(shù)據(jù)進行處理或對視圖進行處理,modelAndView也可能為null。
? ? ?*/
? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
? ? ? ? ? ? ModelAndView modelAndView) throws Exception {
? ? ? ? System.out.println("==========================================post1================================================");
? ? }
? ? /**
? ? ?* 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監(jiān)控中我們可以在此記錄結束時間并輸出消耗時間,還可以進行一些資源清理,類似于try-catch-finally中的finally,但僅調用處理器執(zhí)行鏈中
? ? ?*/
? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================after1================================================");
? ? }
}
package com.bshf.recipe.demo.syslog;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SyslogInterceptor2 implements HandlerInterceptor {
? ? /**
? ? ?* 預處理回調方法,實現(xiàn)處理器的預處理(如檢查登陸),第三個參數(shù)為響應的處理器,自定義Controller
? ? ?* 返回值:true表示繼續(xù)流程(如調用下一個攔截器或處理器);false表示流程中斷(如登錄檢查失?。粫^續(xù)調用其他的攔截器或處理器,此時我們需要通過response來產生響應;
? ? ?*/
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================2================================================");
? ? ? ? return true;
? ? }
? ? /**
? ? ?* 后處理回調方法,實現(xiàn)處理器的后處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數(shù)據(jù)進行處理或對視圖進行處理,modelAndView也可能為null。
? ? ?*/
? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
? ? ? ? ? ? ModelAndView modelAndView) throws Exception {
? ? ? ? System.out.println("==========================================post2================================================");
? ? }
? ? /**
? ? ?* 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監(jiān)控中我們可以在此記錄結束時間并輸出消耗時間,還可以進行一些資源清理,類似于try-catch-finally中的finally,但僅調用處理器執(zhí)行鏈中
? ? ?*/
? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================after2================================================");
? ? }
}
package com.bshf.recipe.demo.syslog;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SyslogInterceptor3 implements HandlerInterceptor {
? ? /**
? ? ?* 預處理回調方法,實現(xiàn)處理器的預處理(如檢查登陸),第三個參數(shù)為響應的處理器,自定義Controller
? ? ?* 返回值:true表示繼續(xù)流程(如調用下一個攔截器或處理器);false表示流程中斷(如登錄檢查失敗),不會繼續(xù)調用其他的攔截器或處理器,此時我們需要通過response來產生響應;
? ? ?*/
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================3================================================");
? ? ? ? return true;
? ? }
? ? /**
? ? ?* 后處理回調方法,實現(xiàn)處理器的后處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數(shù)據(jù)進行處理或對視圖進行處理,modelAndView也可能為null。
? ? ?*/
? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
? ? ? ? ? ? ModelAndView modelAndView) throws Exception {
? ? ? ? System.out.println("==========================================post3================================================");
? ? }
? ? /**
? ? ?* 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監(jiān)控中我們可以在此記錄結束時間并輸出消耗時間,還可以進行一些資源清理,類似于try-catch-finally中的finally,但僅調用處理器執(zhí)行鏈中
? ? ?*/
? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
? ? ? ? ? ? throws Exception {
? ? ? ? System.out.println("==========================================after3================================================");
? ? }
}
<mvc:interceptors>
? ? ? ? <mvc:interceptor>
? ? ? ? ? ? <mvc:mapping path="/**"/>
? ? ? ? ? ? <bean class="com.bshf.recipe.demo.syslog.SyslogInterceptor" />
? ? ? ? </mvc:interceptor>
? ? ? ? <mvc:interceptor>
? ? ? ? ? ? <mvc:mapping path="/**"/>
? ? ? ? ? ? <bean class="com.bshf.recipe.demo.syslog.SyslogInterceptor2" />
? ? ? ? </mvc:interceptor>
? ? ? ? <mvc:interceptor>
? ? ? ? ? ? <mvc:mapping path="/**"/>
? ? ? ? ? ? <bean class="com.bshf.recipe.demo.syslog.SyslogInterceptor3" />
? ? ? ? </mvc:interceptor>
</mvc:interceptors>

<mvc:mapping path="/**"/>需要攔截的路徑,這里匹配所有。

這里的配置順序將是攔截器執(zhí)行順序。

輸出結果:

==========================================1================================================
==========================================2================================================
==========================================3================================================
==========================================post3================================================
==========================================post2================================================
==========================================post1================================================
==========================================after3================================================
==========================================after2================================================
==========================================after1================================================

post和after是倒序的?。。。?/strong>

中斷流程Demo

將SyslogInterceptor3的preHandle方法返回false。

其他不變,再看輸出結果

==========================================1================================================
==========================================2================================================
==========================================3================================================
==========================================after2================================================
==========================================after1================================================

發(fā)現(xiàn)沒有了post,post方法一個都沒有輸出。

不僅如此,你的主程序代碼(xxx.controller的一個接口)都不會被執(zhí)行,所以只要遇到return false,則直接進行after清理工作,post和自己主程序代碼都將被略過。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論

溧阳市| 井研县| 基隆市| 寻乌县| 元谋县| 加查县| 武功县| 玉溪市| 自贡市| 茶陵县| 和硕县| 旌德县| 林西县| 石家庄市| 临泉县| 呼伦贝尔市| 铜山县| 肃南| 西安市| 石首市| 东台市| 夏河县| 晋州市| 宜州市| 吉安县| 响水县| 曲水县| 宁国市| 黄龙县| 依兰县| 天气| 大名县| 韶关市| 锡林郭勒盟| 博客| 阿拉尔市| 嵩明县| 阳曲县| 东安县| 湟源县| 灌云县|