Spring?AOP實(shí)現(xiàn)用戶登錄統(tǒng)一驗(yàn)證功能
一. 用戶登陸統(tǒng)一驗(yàn)證功能
1.1 用戶登錄驗(yàn)證的幾種方法
第一版的用戶登陸驗(yàn)證: 在每個(gè)方法里獲取 session 和 session 中的用戶信息,如果用戶存在,那么就認(rèn)為登陸成功了,否則就失敗了
第二版的用戶登陸驗(yàn)證: 提供統(tǒng)一的方法,在每個(gè)需要驗(yàn)證用戶登陸的方法調(diào)用統(tǒng)一驗(yàn)證用戶登陸的方法來進(jìn)行判斷
第二版的用戶登陸驗(yàn)證: 使用Spring AOP 來使用統(tǒng)一的用戶登陸檢驗(yàn)
遇到的問題:
● 沒有辦法獲取到HttpSession 和 Request 對(duì)象
● 實(shí)際攔截規(guī)則很復(fù)雜,使用簡(jiǎn)單的 aspect j 表達(dá)式無法滿足攔截的需求
第二版的用戶登陸驗(yàn)證: Spring 攔截器來實(shí)現(xiàn)用戶的統(tǒng)一登陸驗(yàn)證功能
● 實(shí)現(xiàn)自定義攔截器 添加@Component注解,實(shí)現(xiàn) Spring為我們提供的 HandlerInterceptor 接口中的 重寫preHandler 方法
(一個(gè)項(xiàng)目中可以配置多個(gè)攔截器).
● 將自定義攔截器加入到框架的配置中去, 并且設(shè)置攔截規(guī)則如下:
(1) 給要將攔截器加入到的當(dāng)前類中 叫@Configuration注解
(2) 實(shí)現(xiàn) WebMvcConfigurer接口
(3) 重寫 addInterceptors方法來實(shí)現(xiàn)需要攔截的頁面,和不需要攔截的頁面(白名單)
這里我們看到之前的代碼里過于耦合,并且繁瑣,接下來我們來學(xué)習(xí)Spring’為我們提供的框架
@RestController @RequestMapping("/user") public class UserController { /** * 某?法 1 */ @RequestMapping("/m1") public Object method(HttpServletRequest request) { // 有 session 就獲取,沒有不會(huì)創(chuàng)建 HttpSession session = request.getSession(false); if (session != null && session.getAttribute("userinfo") != null) { // 說明已經(jīng)登錄,業(yè)務(wù)處理 return true; } else { // 未登錄 return false; } } /** * 某?法 2 */ @RequestMapping("/m2") public Object method2(HttpServletRequest request) { // 有 session 就獲取,沒有不會(huì)創(chuàng)建 HttpSession session = request.getSession(false); if (session != null && session.getAttribute("userinfo") != null) { // 說明已經(jīng)登錄,業(yè)務(wù)處理 return true; } else { // 未登錄 return false; } } // 其他?法... }
1.2 創(chuàng)建前端頁面
登陸頁面:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>登錄頁面</h1> </body> </html>
歡迎頁面:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1> index 頁面</h1> </body> </html>
1.3 創(chuàng)建登陸方法和歡迎進(jìn)入方法
package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @RequestMapping("/user") @RestController public class UserController { // 登陸頁面 @RequestMapping("/login") public boolean login(HttpServletRequest request,String username, String password){ boolean result = false; // 判斷是否在登陸頁面輸入賬號(hào) 和 密碼 if (StringUtils.hasLength(username) && StringUtils.hasLength(password)){ // 驗(yàn)證輸入的賬號(hào) 和 密碼 是否正確 if (username.equals("admin") && password.equals("admin")){ // 判斷輸入的賬號(hào)和密碼正確后 建立一個(gè) session對(duì)象進(jìn)行存儲(chǔ) HttpSession session = request.getSession(); session.setAttribute("userinfo","userinfo"); return true; } } return result; } // 歡迎頁面 @RequestMapping("/index") public String index() { return "Hello,Index"; }
1.4 自定義一個(gè)攔截器
對(duì)于以上問題 Spring 中提供了具體的實(shí)現(xiàn)攔截器:HandlerInterceptor,攔截器的實(shí)現(xiàn)分為以下兩個(gè)步驟:
創(chuàng)建?定義攔截器,實(shí)現(xiàn) HandlerInterceptor 接?的 preHandle(執(zhí)?具體?法之前的預(yù)處理)?法
將?定義攔截器加?實(shí)現(xiàn)接口 WebMvcConfigurer 類的,重寫 addInterceptors ?法中
具體實(shí)現(xiàn)如下:
創(chuàng)建?定義攔截器:
package com.example.demo.config; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * 自定義登陸用戶登陸攔截器 */ @Component public class LoginIntercept implements HandlerInterceptor { /** * 返回 ture 表示攔截判斷通過, 可以訪問后面的接口, 如果返回false 表示攔截未通過,直接返回結(jié)果給前端 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(false); if (session != null && session.getAttribute("userinfo") != null ){ // 表示已經(jīng)登陸 return true; } // 使用重定向方法 將表示未登錄,就可以使用戶跳轉(zhuǎn)登陸頁面 response.sendRedirect("/login.html"); return false; } }
將自定義攔截器加入到框架的配置中去
package com.example.demo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; //配置存儲(chǔ) @Configuration public class AppConfig implements WebMvcConfigurer { // 通過屬性注入到攔截器 // 通過注入攔截器來配置規(guī)則 @Autowired private LoginIntercept loginIntercept; @Override public void addInterceptors(InterceptorRegistry registry) { //通過registry.addInterceptor可以得到攔截器 // 登陸攔截 需要 通過屬性注入來獲取有l(wèi)oginIntercept攔截器對(duì)象執(zhí)行攔截方法 // addPathPatterns 是攔截方法 // excludePathPatterns 不攔截方法是 registry.addInterceptor(loginIntercept) .addPathPatterns("/**") //攔截所有 的url .excludePathPatterns("/user/login") //不攔截登陸 .excludePathPatterns("/user/reg") //不攔截注冊(cè)頁面 .excludePathPatterns("/login.html") //不攔截登陸 .excludePathPatterns("/reg.html") //不攔截注冊(cè)頁面 .excludePathPatterns("/**/*.js") //所有的js都不攔截 .excludePathPatterns("/**/*.css") //所有的css都不攔截 .excludePathPatterns("/**/*.png"); //所有的png照片都不攔截 } // 給所有請(qǐng)求地址添加 訪問頁面 帶有api 前綴 // @Override // public void configurePathMatch(PathMatchConfigurer configurer) { // configurer.addPathPrefix("api",c -> true); // } }
1.5 驗(yàn)證攔截功能
1.5.1 當(dāng)沒有進(jìn)行登陸,進(jìn)入歡迎頁面
當(dāng)我們?cè)跊]有進(jìn)行登陸時(shí),直接輸入歡迎頁面時(shí)
我們通過重定向的方法就可以將用戶引導(dǎo)到登陸頁面中
1.5.2 當(dāng)用戶未成功輸入正確用戶名和密碼
我們會(huì)返回一個(gè) false結(jié)果來提醒用戶輸入的用戶名和密碼錯(cuò)誤
1.5.3 當(dāng)用戶成功輸入正確用戶名和密碼后登陸歡迎頁面
我們先進(jìn)行用戶登陸成功操作
再次輸入歡迎頁面,我們就可以看到歡迎頁面的內(nèi)容啦!
1.5.4 使用前綴方法進(jìn)行登陸
上文我們可以使用
// 給所有請(qǐng)求地址添加 訪問頁面 帶有api 前綴 @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.addPathPrefix("api",c -> true); }
1.6 小結(jié)
通過上?的源碼分析,我們可以看出,Spring 中的攔截器也是通過動(dòng)態(tài)代理和環(huán)繞通知的思想實(shí)現(xiàn)的,?體的調(diào)?流程如下:
以上就是Spring AOP實(shí)現(xiàn)用戶登錄統(tǒng)一驗(yàn)證功能的詳細(xì)內(nèi)容,更多關(guān)于Spring AOP用戶登錄統(tǒng)一驗(yàn)證的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot使用AOP與注解實(shí)現(xiàn)請(qǐng)求參數(shù)自動(dòng)填充流程詳解
- SpringBoot使用AOP實(shí)現(xiàn)統(tǒng)計(jì)全局接口訪問次數(shù)詳解
- spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù)
- 基于springboot實(shí)現(xiàn)一個(gè)簡(jiǎn)單的aop實(shí)例
- spring aop底層原理及如何實(shí)現(xiàn)
- SpringAop實(shí)現(xiàn)操作日志記錄
- Spring AOP 的組成和實(shí)現(xiàn)
相關(guān)文章
Java List分頁功能實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了Java List分頁功能實(shí)現(xiàn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01解決@PathVariable對(duì)于特殊字符截?cái)嗟膯栴}
這篇文章主要介紹了解決@PathVariable對(duì)于特殊字符截?cái)嗟膯栴},具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02SpringBoot2.0.3打印默認(rèn)數(shù)據(jù)源為 HikariDataSource (null)問題
這篇文章主要介紹了SpringBoot2.0.3打印默認(rèn)數(shù)據(jù)源為 HikariDataSource (null)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java?ArrayList遍歷foreach與iterator時(shí)remove的區(qū)別
這篇文章主要介紹了Java?ArrayList遍歷foreach與iterator時(shí)remove的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07解析電子郵件的基本概念及JavaMail API郵件功能使用
這篇文章主要介紹了電子郵件的基本概念及JavaMail API郵件功能使用,包括用Java來發(fā)送郵件的示例,需要的朋友可以參考下2016-02-02SpringBoot使用Editor.md構(gòu)建Markdown富文本編輯器示例
這篇文章主要介紹了SpringBoot使用Editor.md構(gòu)建Markdown富文本編輯器示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12java實(shí)現(xiàn)定制數(shù)據(jù)透視表的示例詳解
數(shù)據(jù)透視表(Pivot?Table)是一種數(shù)據(jù)分析工具,通常用于對(duì)大量數(shù)據(jù)進(jìn)行匯總、分析和展示,本文主要介紹了如何使用Java將計(jì)算項(xiàng)添加到數(shù)據(jù)透視表中,感興趣的可以了解下2023-12-12Java實(shí)現(xiàn)視頻初步壓縮和解壓的代碼示例
從攝像頭讀取每一幀的圖片,用一些簡(jiǎn)單的方法將多張圖片信息壓縮到一份文件中(自定義的視頻文件),自定義解碼器讀取視頻文件,并將每幀圖片展示成視頻,本文主要介紹了Java實(shí)現(xiàn)視頻初步壓縮和解壓,需要的朋友可以參考下2023-10-10