【建議使用】告別if,Java超好用引數校驗工具類
一、前言
今天和小夥伴們分享一個常用的工具類,共計四個方法,使用場景比較廣泛,有用於校驗某個物件或物件中指定屬性為空值時,直接返回異常,常用語校驗前端請求引數;也有當值不為空時,執行指定動作,可減少大量的if條件,如:mybatis請求引數設定;還有用於判斷當值不為空時,替代為新值,完成後續動作。
這樣描述可能不夠清晰,這裡我列舉了幾個使用場景,更多的場景需要小夥伴們根據自己業務需求合理使用。
//場景一,點選登入時,後端校驗使用者名稱
if(StringUtils.isEmpty(name)){
throw new Exception("登入使用者名稱不能為空");
}
//場景二:屬性內容轉換為新值
String address = "浙江省杭州市";
if(StringUtils.isNotEmpty(address)){
address ="地址:"+address;
}
//場景三:替代過多的if條件
SysUserDto userDto = new SysUserDto();//前端引數
SysUser user = new SysUser();//mybatis引數
if(StringUtils.isEmpty(userDto.getName())){
user.setUserName(userDto.getName())
}
if(StringUtils.isEmpty(userDto.getPwd())){
user.setPassword(userDto.getPwd())
}
複製程式碼
\
二、正文
首先建立一個測試實體類:
import lombok.Data;
@Data
public class SysUser{
private String name;
private String password;
}
複製程式碼
2.1 檢查多個物件不能為空
- 測試範例
SysUser user = new SysUser();
SysUser user2 = null;
Args.notEmptys(user,user2);
複製程式碼
- 方法內容
public static void notEmptys(Object... objects) {
for (Object obj : objects) {
if (obj == null) {
throw new BusinessException("屬性不能為空");
}
if (obj.toString().trim().isEmpty()) {
throw new BusinessException("屬性不能為空");
}
}
}
複製程式碼
- 測試結果
Exception in thread "main" 屬性不能為空
at com.basic.business.utils.Args.notEmptys(Args.java:27)
at com.basic.business.demo.DemoController.main(DemoController.java:43)
複製程式碼
2.2 校驗物件屬性不能為空
若將引數【Boolean isAll】設定為true,則會校驗全部屬性;若設定為false,就需要將檢測欄位放入【propertys】中。
- 測試範例
SysUser user = new SysUser();
//用法一:校驗全部引數
Args.checkField(user,true,"");
//用法二:只校驗password引數
Args.checkField(user,false,"password");
複製程式碼
- 方法內容
/**
* 物件多欄位判空檢查
* @param obj 被檢查的物件
* @param isAll 是否檢查全部引數
* @param propertys 被檢查物件中的欄位 可多個
*/
public static void checkField(Object obj, Boolean isAll, String... propertys) {
if (obj != null) {
Class<? extends Object> clazz = obj.getClass();
if (isAll) {
PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz);
for (int p = 0; p < propertyDescriptors.length; p++) {
checkEachField(obj, propertyDescriptors[p]);
}
} else {
if (propertys != null && propertys.length > 0) {
//遍歷所有屬性
for (int i = 0; i < propertys.length; i++) {
String property = propertys[i];
//獲取屬性資訊
BeanUtils.getPropertyDescriptors(clazz);
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, property);
checkEachField(obj, pd);
}
}
}
}
}
private static void checkEachField(Object obj, PropertyDescriptor pd) {
Class<? extends Object> clazz = obj.getClass();
String property = pd.getName();
if (pd != null) {
//獲取當前欄位的javabean讀方法
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
Object invoke = null;
try {
invoke = readMethod.invoke(obj);
} catch (Exception e) {
throw new BusinessException("方法 " + readMethod.getName() + "無法執行");
}
if (invoke != null) {
//String型別單獨處理
Class<?> propertyType = pd.getPropertyType();
if ("java.lang.String".equals(propertyType.getName())) {
if (StringUtils.isBlank((String) invoke)) {
throw new BusinessException("錯誤 : [ " + property + " ] 不能為空!");
}
} else if ("java.util.List".equals(propertyType.getName())) {
List list = (List) invoke;
if (list.size() == 0) {
throw new BusinessException("錯誤 : [ " + property + " ] 不能為空!");
}
}
} else {
throw new BusinessException("錯誤 : [ " + property + " ] 不能為空!");
}
} else {
throw new BusinessException("在 " + clazz + "中 找不到" + "[ " + property + " ] 的 讀方法");
}
} else {
throw new BusinessException("在 " + clazz + "中 找不到" + "[ " + property + " ] 屬性");
}
}
複製程式碼
- 測試結果
用法一結果:
Exception in thread "main" 錯誤 : [ name ] 不能為空!
at com.basic.business.utils.Args.checkEachField(Args.java:116)
at com.basic.business.utils.Args.checkField(Args.java:77)
用法二結果:
Exception in thread "main" 錯誤 : [ password ] 不能為空!
at com.basic.business.utils.Args.checkEachField(Args.java:116)
at com.basic.business.utils.Args.checkField(Args.java:77)
複製程式碼
2.3 引數不為空時執行指定動作
我們經常會遇到這種場景,根據前端引數來組裝資料庫查詢條件,如果不為空我們就將前端值設定到是實體類中,或者如下面這個例子中,當name不為空時,加入到list當中。
- 測試範例
List list = Lists.newArrayList();
SysUser user = new SysUser();
user.setName("huage");
Args.doIfNotEmpty(user.getName(),list::add);
System.out.println(list);
複製程式碼
- 方法內容
public static <R, T> R doIfNotNull(T t, Callback<T, R> callback) {
try {
return t == null ? null : callback.call(t);
} catch (Exception e) {
throw new BusinessException("[doIfNotNull error]", e);
}
}
複製程式碼
- 測試結果
[huage]
複製程式碼
2.4 引數為空時使用新值,並完成指定動作
本方法和2.較為類似,只是當目標值不為空時,使用新值進行後續的操作,如下面這個例子中,name初始值為【test】,執行完doIfNotNullNewValue後會將新值【huage】新增到list中,。
- 測試範例
List list = Lists.newArrayList();
SysUser user = new SysUser();
user.setName("test");
Args.doIfNotNullNewValue(user.getName(),"huage",list::add);
System.out.println(list);
複製程式碼
- 方法內容
public static <R, T> R doIfNotNullNewValue(T t,T newt, Callback<T, R> callback) {
try {
return t == null ? null : callback.call(newt);
} catch (Exception e) {
throw new BusinessException("[doIfNotNull error]", e);
}
}
複製程式碼
- 測試結果
[huage]
最後
如果你覺得此文對你有一丁點幫助,點個贊。或者可以加入我的開發交流群:1025263163相互學習,我們會有專業的技術答疑解惑
如果你覺得這篇文章對你有點用的話,麻煩請給我們的開源專案點點star:https://gitee.com/ZhongBangKeJi/crmeb_java不勝感激 !
「其他文章」
- 遵循Promises/A 規範,深入分析Promise實現細節 | 通過872測試樣例
- 80 行程式碼實現簡易 RxJS
- 前後端分離專案,如何解決跨域問題?
- springboot中攔截並替換token來簡化身份驗證
- 15 行程式碼在 wangEditor v5 使用數學公式
- Java執行緒池必知必會
- EdgeDB 架構簡析
- TS 型別體操:圖解一個複雜高階型別
- 基於babel的埋點工具簡單實現及思考
- 使用craco對cra專案進行構建優化
- Netty核心概念之ChannelHandler&Pipeline&ChannelHandlerContext
- 理解python非同步程式設計與簡單實現asyncio
- Mycat 作為代理服務端的小知識點
- 一文吃透 React Expiration Time
- 前端模組化詳解
- Java必備主流技術流程圖
- 【建議使用】告別if,Java超好用引數校驗工具類
- MySQL模糊查詢再也不用like %了
- Java 8 的Stream流那麼強大,你知道它的原理嗎
- Vue SEO的四種方案