SpringBoot實現參數校驗攔截(采用AOP方式)

一、AOP是什么?

目的:分離橫切關注點(如日志記錄、事務管理)與核心業務邏輯。

優勢:提高代碼的可讀性和可維護性。

關鍵概念

  • 切面(Aspect):包含橫切關注點代碼的模塊。
  • 通知(Advice):切面中的具體動作,比如方法調用之前或之后執行的代碼。
  • 連接點(Join Point):程序執行的某個具體點,比如方法調用。
  • 切入點(Pointcut):定義在哪些連接點應用通知。

二、使用步驟

1.引入庫

代碼如下(示例):

<dependencies><!-- 引入SpringBoot Aop依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- 引入Aspectj依賴 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency>
</dependencies>

2.定義注解

定義注解GlobalInterceptor

代碼示例:如下

@Target({ElementType.METHOD})//注解的目標類型是方法
@Retention(RetentionPolicy.RUNTIME)//注解在運行的時候生效
@Documented
@Mapping
public @interface GlobalInterceptor {/*** 校驗參數* @return*/boolean checkParams() default false;
}

?定義注解用來校驗具體參數

@Retention(RetentionPolicy.RUNTIME)//運行時校驗
@Target({ElementType.PARAMETER,ElementType.FIELD})// 指定該注解可以應用的目標類型為參數和字段
public @interface VerifyParam {int min() default -1;//校驗最小長度int max() default -1;//檢驗最大長度boolean required() default false; //校驗是否必傳VerifyRegexEnum regex() default VerifyRegexEnum.NO;//校驗正則,默認狀態是不校驗的}

?可以看到上方的VerifyRegexEnum,這里是一個枚舉,主要是來校驗參數的,那么枚舉代碼示例如下:

public enum VerifyRegexEnum {NO("","不校驗"),EMAII("^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$","郵箱"),PASSWORD("^(?=.*\\d)(?=.*[a-zA-Z])[\\da-zA-Z~!@#$號^&* ]{8,}$","只能是數字,字母,特殊字符 8-18位");private String regex;private String desc;VerifyRegexEnum(String regex, String desc) {this.regex = regex;this.desc = desc;}public String getRegex() {return regex;}public String getDesc() {return desc;}
}

?由于這里我的項目中只是簡單的校驗了一下郵箱和密碼,需要的話,大家可以自行加入校驗方式

?3.定義切面類

@Aspect//表明這是一個切面類
@Component("globalOperatcionAspect")// 交給Spring管理
public class GlobalOperatcionAspect {private static final Logger logger = LoggerFactory.getLogger(GlobalOperatcionAspect.class);private static final String[] TYPE_BASE = {"java.lang.String","java.lang.Integer","java.lang.Long"};//@Pointcut 定義切入點表達式,用于匹配目標方法,此處匹配帶有@GlobalInterceptor注解的方法@Pointcut("@annotation(com.easypan.annotation.GlobalInterceptor)")private void requestInterceptor(){// 方法體為空,只是作為一個切入點標識}//@Before 在目標方法執行前執行@Before("requestInterceptor()")public void interceptorDo(JoinPoint point) throws BusinessException {try {Object target = point.getTarget();// 獲取目標對象Object[] arguments = point.getArgs(); // 獲取方法參數String methodName = point.getSignature().getName(); // 獲取方法名Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes(); // 獲取方法參數類型Method method = target.getClass().getMethod(methodName, parameterTypes); // 獲取目標方法GlobalInterceptor interceptor = method.getAnnotation(GlobalInterceptor.class); // 獲取方法上的全局攔截器注解if (null == interceptor) { // 如果注解為空則不執行攔截器邏輯return;}/*** 檢驗參數*/if (interceptor.checkParams()) { // 如果需要檢驗參數validateParams(method, arguments); // 執行參數校驗}} catch (BusinessException e) {logger.error("全局攔截器異常", e); // 記錄異常日志throw e; // 拋出業務異常} catch (Exception e) {logger.error("全局攔截器異常", e); // 記錄異常日志throw new BusinessException(ResponseCodeEnum.CODE_500); // 拋出業務異常} catch (Throwable e) {logger.error("全局攔截器異常", e); // 記錄異常日志throw new BusinessException(ResponseCodeEnum.CODE_500); // 拋出業務異常}}/*** 檢驗規則* @param method 方法* @param arguments 參數列表*/private void validateParams(Method method, Object[] arguments) {Parameter[] parameters = method.getParameters(); // 獲取方法參數列表for (int i = 0; i < parameters.length; i++) { // 遍歷參數列表Parameter parameter = parameters[i]; // 獲取參數Object value = arguments[i]; // 獲取參數值VerifyParam verifyParam = parameter.getAnnotation(VerifyParam.class); // 獲取參數上的校驗注解if (verifyParam == null) { // 如果注解為空則跳過continue;}if (ArrayUtils.contains(TYPE_BASE, parameter.getParameterizedType().getTypeName())) { // 如果是基本類型checkValue(value, verifyParam); // 執行值校驗} else {checkBObjValue(parameter, value); // 執行對象值校驗}}}/*** 對象值校驗* @param parameter 參數* @param value 參數值*/private void checkBObjValue(Parameter parameter, Object value) {try {String typeName = parameter.getParameterizedType().getTypeName(); // 獲取參數類型名Class classz = Class.forName(typeName); // 獲取類對象Field[] fields = classz.getDeclaredFields(); // 獲取類的所有字段for (Field field : fields) { // 遍歷字段VerifyParam fieldVerifyParam = field.getAnnotation(VerifyParam.class); // 獲取字段上的校驗注解if (fieldVerifyParam == null) { // 如果注解為空則跳過continue;}field.setAccessible(true); // 設置字段可訪問Object resultValue = field.get(value); // 獲取字段值checkValue(resultValue, fieldVerifyParam); // 執行值校驗}} catch (BusinessException e) {logger.error("校驗參數失敗", e); // 記錄異常日志throw e; // 拋出業務異常} catch (Exception e) {logger.error("校驗參數失敗", e); // 記錄異常日志throw new BusinessException(ResponseCodeEnum.CODE_600); // 拋出業務異常}}/*** 值校驗* @param value 值* @param verifyParam 校驗參數*/private void checkValue(Object value, VerifyParam verifyParam) {Boolean isEmpty = value == null || StringTools.isEmpty(value.toString()); // 判斷值是否為空Integer length = value == null ? 0 : value.toString().length(); // 獲取值長度/*** 檢驗空*/if (isEmpty && verifyParam.required()) { // 如果值為空且需要校驗空throw new BusinessException(ResponseCodeEnum.CODE_600); // 拋出業務異常}/*** 檢驗長度*/if (!isEmpty && (verifyParam.max() != -1 && verifyParam.max() < length) || (verifyParam.min() != -1 && verifyParam.min() > length)) { // 如果值不為空且長度不符合規則throw new BusinessException(ResponseCodeEnum.CODE_600); // 拋出業務異常}/*** 校驗正則*/if (!isEmpty && !StringTools.isEmpty(verifyParam.regex().getRegex()) && !VerifyUtils.verify(verifyParam.regex(), String.valueOf(value))) { // 如果值不為空且不符合正則規則throw new BusinessException(ResponseCodeEnum.CODE_600); // 拋出業務異常}}
}

總結

?去瀏覽器直接調用這個路徑,沒有傳參數的話,報錯

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/24397.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/24397.shtml
英文地址,請注明出處:http://en.pswp.cn/web/24397.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【2024最新華為OD-C/D卷試題匯總】[支持在線評測] 運輸時間(200分) - 三語言AC題解(Python/Java/Cpp)

?? 大家好這里是清隆學長 ,一枚熱愛算法的程序員 ? 本系列打算持續跟新華為OD-C/D卷的三語言AC題解 ?? ACM銀牌??| 多次AK大廠筆試 | 編程一對一輔導 ?? 感謝大家的訂閱? 和 喜歡?? ??在線評測鏈接 運輸時間(200分) ?? 評測功能需要訂閱專欄后私信聯系清隆解…

【面試干貨】索引的優缺點

【面試干貨】索引的優缺點 1、創建索引可以大大提高系統的性能&#xff08;**優點**&#xff09;2、增加索引也有許多不利的方面&#xff08;**缺點**&#xff09; &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收藏不迷路&#x1f496; 1、創建索引可以大大提高系…

LiDAR360MLS 7.2.0 雷達點云數據處理軟件功能介紹

新增模塊和功能: 支持手持、背包數據的解算 SLAM解算成功率提升 SLAM解算效率提升 采集端與后處理端保持一致 賦色優化 新增平面圖模塊 新增平面圖全自動矢量化功能 新增平面圖矢量一鍵導出DXF功能 新增平面圖正射影像一鍵導出功能 支持交叉、垂直繪制 支…

添加west擴展命令

使用west工具的幫助命令&#xff0c;west -h&#xff0c;不僅可以列出west工具的內置命令&#xff0c;也可以列舉當前工程中實現的擴展命令&#xff0c;如build&#xff0c;flash等。 本文將介紹如何添加擴展命令。 west擴展命令的位置通過以下方式查找&#xff1a; 1. 首先找…

kafka消息積壓處理方案

背景&#xff1a; 某值班的一天&#xff0c;生產出現消息積壓問題&#xff0c;對此類的問題做出快速應對方案來避免同類型問題&#xff0c;防止影響范圍進一步的擴大。 出現消費積壓后如何處理&#xff1a; 首先優先處理消息積壓&#xff0c;如果代碼邏輯問題&#xff0c;立…

【第12章】SpringBoot實戰篇之文件上傳(含阿里云OSS上傳)

文章目錄 前言一、本地文件上傳二、阿里云OSS上傳1. 環境準備2.安裝SDK3.使用長期訪問憑證3.1 獲取RAM用戶的訪問密鑰3.2 配置RAM用戶的訪問密鑰(Linux)3.3 從環境變量中獲取RAM用戶的訪問密鑰 4. 工具類5.使用 總結 前言 本章節介紹本地文件上傳和阿里云OSS上傳。 一、本地文…

Python 機器學習 基礎 之 【實戰案例】輪船人員獲救預測實戰

Python 機器學習 基礎 之 【實戰案例】輪船人員獲救預測實戰 目錄 Python 機器學習 基礎 之 【實戰案例】輪船人員獲救預測實戰 一、簡單介紹 二、輪船人員獲救預測實戰 三、數據處理 1、導入數據 2、對缺失數據的列進行填充 3、屬性轉換&#xff0c;把某些列的字符串值…

LSTM-Adaboost基于雙向長短期記憶網絡結合集成學習實現股價預測附matlab代碼

% 股價預測 - LSTM-Adaboost集成學習 % 加載股價數據 load(‘stock_data.mat’); % 假設數據已經存儲在stock_data.mat文件中 prices stock_data.prices; % 假設股價數據存儲在名為prices的變量中 % 數據預處理 normalized_prices (prices - mean(prices)) / std(prices); …

數組中尋找符合條件元素的位置(np.argwhere,nonzero)

今天遇到一個問題&#xff0c;就是尋找符合條件的元素所在的位置&#xff0c;主要使用np.argwhere和nonzero函數 比如給我一個二維數組&#xff0c;我想知道其中元素大于15的位置 方法1 import numpy as np exnp.arange(30) enp.reshape(ex,[3,10]) print(e) print(e>15…

南山代理記賬,為您提供專業、高效的服務和全方位的支持

隨著商業活動的不斷深化和擴展&#xff0c;企業的會計工作越來越重要&#xff0c;而作為一家專業的代理記賬公司&#xff0c;“南山代理記賬”始終致力于為客戶提供專業、高效的服務&#xff0c;幫助他們在經營過程中更好地管理和運用資金。 南山代理記賬公司的服務范圍廣泛&am…

【日記】遇到了一個 “不愿睜眼看世界也沒受過社會毒打” 的逆天群友(464 字)

正文 今天坐在柜臺玩了一天手機…… 手機都玩沒電了快。下午在勸一個群友睜眼看世界&#xff0c;實在勸不動。他真的太逆天了&#xff0c;我不清楚這么高學歷的人&#xff0c;怎么能說出這么天真的話。逆天又離譜。 晚上的時間幾乎全在做家務。平時晚上都是跳舞來著&#xff0c…

mac安裝brew遇到的一些問題

mac終端執行命令/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”&#xff0c;無法建立連接或連接超時錯誤&#xff0c;錯誤信息如下&#xff1a; curl: (28) Failed to connect to raw.githubusercontent.com port 443 af…

標準價與移動平均價簡介

一、移動平均價 移動平均價優點&#xff1a; a.移動平均價格可反應”實時的”加權平均價格,特別是物料價格漲跌幅度大時物料的價格不會被差異扭曲。 b.因為是基于交易的實時加權平均計算價格,一般情況下,移動平均價不產生差異&#xff0c;價格相對真實。 c.如果所有的物料都使用…

module ‘django_cas_ng.views‘ has no attribute ‘login‘

這個錯誤表明你正在嘗試從django_cas_ng.views模塊中訪問一個名為login的屬性&#xff0c;但是這個模塊中并沒有名為login的屬性或方法。 解決這個問題&#xff0c;你需要確認你的代碼中是否有錯誤的引用。django_cas_ng是一個CAS&#xff08;Central Authentication Service&…

mqtt-emqx:keepAlive機制測試

mqtt keepAlive原理詳見【https://www.emqx.com/zh/blog/mqtt-keep-alive】 # 下面開始寫測試代碼 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2…

Ubuntu項目部署

解壓jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 配置Java環境變量&#xff1a; vim ~/.bashrc export JAVA_HOME/root/soft/jdk1.8.0_151 export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH 設置環境變…

Python中的面向對象編程(OOP):概念、實踐與優勢

Python中的面向對象編程(OOP):概念、實踐與優勢 面向對象編程(Object-Oriented Programming,簡稱OOP)是一種程序設計模型,它將對象作為程序的基本單元,以提高代碼的可重用性、靈活性和擴展性。Python作為一種高級編程語言,對OOP提供了強大的支持。本文將詳細闡述Pyth…

武漢理工大學 云計算與服務計算 期末復習

云計算與的定義 長定義是&#xff1a;“云計算是一種商業計算模型。它將計算任務分布在大量計算機構成的資源池上&#xff0c;使各種應用系統能夠根據需要獲取計算力、存儲空間和信息服務。” 短定義是&#xff1a;“云計算是通過網絡按需提供可動態伸縮的廉價計算服務。 云計…

Lecture1——對最優化的介紹

一&#xff0c;簡介——什么是最優化&#xff1f; 1&#xff0c;三種問題&#xff1a; 用80米的圍欄盡可能的圍成一個面積最大的矩形如何規劃產品的生產&#xff0c;使得公司獲得的利潤最大給你一個圖&#xff08;Graph&#xff09;&#xff0c;如何獲得最短的距離 2&#xf…

MATLAB基礎應用精講-【數模應用】主成分(pca)分析(補充篇)(附MATLAB、R語言和python代碼實現)

目錄 前言 幾個高頻面試題目 主成分分析(PCA)與獨立成分分析(ICA) 1. 技術背景 2. 主成分分析 3. 獨立成分分析 算法原理 數據降維 PCA 涉及的主要問題 PCA 的優化目標 主成分分析(PCA)的基本思想 數學模型 協方差和散度矩陣 PCA的推導:基于最小投影距離 ?…