Spring MVC實(shí)現(xiàn)的登錄攔截器代碼分享
之前接觸過struts攔截器,但是沒有使用過Spring MVC攔截器,今天花了一天時(shí)間好好研究了一下。
本文首先介紹了攔截器的基本概念,然后向大家闡述攔截器與過濾器的簡(jiǎn)要區(qū)別,通過HandlerInterceptor 接口中定義的三個(gè)方法實(shí)現(xiàn)攔截器功能,最后介紹了配置相關(guān)的代碼,接下來看看具體內(nèi)容。
定義攔截器
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的類。
攔截器的使用場(chǎng)景:解決亂碼問題,解決權(quán)限驗(yàn)證問題 使用原則:處理所有請(qǐng)求的共同遇到的問題
攔截器和過濾器的區(qū)別
過濾器Filter依賴于Servlet容器,基于回調(diào)函數(shù),過濾范圍大
攔截器Interceptor依賴于框架容器,基于反射機(jī)制,只過濾請(qǐng)求
攔截器可以處理Web應(yīng)用中請(qǐng)求的一些通用性問題
共性問題在攔截器中處理,可以減少重復(fù)代碼,便于維護(hù)
實(shí)現(xiàn)HandlerInterceptor接口
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)行資源清理工作的。
我試著做了一個(gè)簡(jiǎn)單的登錄攔截,根據(jù)session中是否有信息來進(jìn)行判斷.以下是代碼,代碼很簡(jiǎn)單,控制器中判斷用戶名密碼是否正確,然后將用戶信息保存到session中,方法如下:
/*
* 判斷用戶的登錄信息 ,注意此方法不能攔截,否則攔截器獲取不到session中的信息
*/
@RequestMapping("/indexManagerUser/managerLogin")
public String userLogin(HttpServletRequest request,HttpServletResponse response,String userName,String passWord){
logger.info("STEP INTO --> ManagerUserController.userLogin()");
//打印出狀態(tài)
if(userName == null || passWord == null){
//對(duì)用戶名密碼進(jìn)行判空處理
return "manager/error/loginError";
//返回到登錄錯(cuò)誤界面
}
ManagerUser managerUser = managerUserService.userLogin(userName,passWord);
//調(diào)用service判斷用戶名密碼是否正確
if(managerUser != null){
//如果用戶信息不為空,將用戶信息保存到session中
HttpSession session = request.getSession();
session.setAttribute("managerUser", managerUser);
session.setMaxInactiveInterval(1800);
return "manager/systemSet/welcome";
} else{
return "manager/error/loginError";
}
}
攔截器如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.elushunfeng.model.ManagerUser;
public class ManagerUserInterceptor extends HandlerInterceptorAdapter{
private static Logger logger = Logger.getLogger(ManagerUserInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
/*
* 從session中獲取用戶信息
*/
ManagerUser managerUser = (ManagerUser) request.getSession().getAttribute("managerUser");
if(managerUser == null){//如果session中沒有用戶的信息,跳轉(zhuǎn)到登錄頁面,內(nèi)部網(wǎng)頁不能訪問
logger.info("ManagerUserInterceptor---->>>>>>preHandle");
request.getRequestDispatcher("/index.jsp").forward(request, response);
return false;
}else
return true;
}
}
攔截器完成以后,需要在配置文件中進(jìn)行配置,
配置如下,
<mvc:interceptors>
<!-- 配置訪問攔截器 -->
<mvc:interceptor>
<mvc:mapping path="/"/><!-- 我這里邊是對(duì)方法分開進(jìn)行攔截的 -->
<mvc:mapping path="/payAliPay/**" />
<mvc:mapping path="/logistics/**" />
<mvc:mapping path="/petroleumOrder/**" />
<mvc:mapping path="/petroleum/**" />
<mvc:mapping path="/carousel/**" />
<mvc:mapping path="/managerUser/**" />
<mvc:mapping path="/user/queryCheckUsers/**" />
<bean id="managerUserInterceptor" class="com.elushunfeng.manager.interceptor.ManagerUserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
總結(jié)
以上就是本文關(guān)于Spring MVC實(shí)現(xiàn)的登錄攔截器代碼分享的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:SpringMVC使用MultipartFile 實(shí)現(xiàn)異步上傳方法介紹、SpringMVC在啟動(dòng)完成后執(zhí)行方法源碼解析等。如有不足之處,歡迎留言指出。小編會(huì)及時(shí)回復(fù)大家并進(jìn)行修改。感謝朋友們對(duì)腳本之家的支持!
相關(guān)文章
SpringBoot2.0整合WebSocket代碼實(shí)例
這篇文章主要介紹了SpringBoot2.0整合WebSocket代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
淺談hashmap為什么查詢時(shí)間復(fù)雜度為O(1)
這篇文章主要介紹了hashmap為什么查詢時(shí)間復(fù)雜度為O(1),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
舉例解析Java多線程編程中需要注意的一些關(guān)鍵點(diǎn)
這篇文章主要介紹了Java多線程編程中需要注意的一些關(guān)鍵點(diǎn),包括ThreadLocal變量與原子更新等一些深層次的內(nèi)容,需要的朋友可以參考下2015-11-11
java基礎(chǔ)篇之Date類型最常用的時(shí)間計(jì)算(相當(dāng)全面)
這篇文章主要給大家介紹了關(guān)于java基礎(chǔ)篇之Date類型最常用的時(shí)間計(jì)算的相關(guān)資料,Java中的Date類是用來表示日期和時(shí)間的類,它提供了一些常用的方法來處理日期和時(shí)間的操作,需要的朋友可以參考下2023-12-12
java 集合之實(shí)現(xiàn)類ArrayList和LinkedList的方法
下面小編就為大家?guī)硪黄猨ava 集合之實(shí)現(xiàn)類ArrayList和LinkedList的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
Java中Runnable和Callable分別什么時(shí)候使用
提到 Java 就不得不說多線程了,就算你不想說,面試官也得讓你說呀,那說到線程,就不得不說Runnable和Callable這兩個(gè)家伙了,二者在什么時(shí)候使用呢,下面就來和簡(jiǎn)單講講2023-08-08
java編程實(shí)現(xiàn)屏幕截圖(截屏)代碼總結(jié)
這篇文章主要介紹了java編程實(shí)現(xiàn)屏幕截圖(截屏)代碼,結(jié)合3個(gè)實(shí)例總結(jié)分析了Java截屏?xí)r頁面抓取及圖片保存的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
關(guān)于Java8新特性O(shè)ptional類的詳細(xì)解讀
Optional類是一個(gè)容器類,它可以保存類型T的值,代表這個(gè)值存在。或者僅僅保存null,表示這個(gè)值不存在,原來用 null 表示一個(gè)值不存在,現(xiàn)在Optional 可以更好的表達(dá)這個(gè)概念。并且可以避免空指針異常,需要的朋友可以參考下2023-05-05
springboot利用aop實(shí)現(xiàn)接口異步(進(jìn)度條)的全過程
我們?cè)陂_發(fā)中,調(diào)用第三方接口時(shí),往往是提交數(shù)據(jù),要異步去獲取數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于springboot利用aop實(shí)現(xiàn)接口異步(進(jìn)度條)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01

