在项目开发中判空是很常见的事,有时候来自前端页面的表单需要挨个判空,如果挨个“null == object”就会变得很臃肿,针对这种情况对判空做个简化。
这是java8的判空方法,一行搞定
/**
* 校验参数是否为空
* @param obj 参数
* @param message 提示信息
*/
public static void checkParam(Object obj, String message) {
Optional.ofNullable(obj).orElseThrow(() -> new RuntimeException(message));
}
那JavaBean呢?需要获取先获取属性名和属性值,通过下面的两个方法实现
/**
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
*/
public static List<Map> getFiledsInfo(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
List<Map> list = new ArrayList<>();
Map<String, Object> infoMap = null;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap<>();
infoMap.put("type", fields[i].getType().toString()); //属性类型,判空一般不需要
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
list.add(infoMap);
}
return list;
}
/**
* 根据属性名获取属性值
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[]{
});
Object value = method.invoke(o, new Object[]{
});
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
这是我定义的一个测试类
@Data
public class DCAGPPDFParam {
//付款账户
private String payeac;
//开始日期
//YYYY-MM-DD 格式
private String begdat;
//结束日期
//YYYY-MM-DD 格式
private String enddat;
//业务类型
//代发工资:N03010, 其他:N03020
private String buscod;
//业务模式
/**
* 对应业务类型的业务模式,查询的账号需要在该业务模式的可经办账号列表里面
*/
private String busmod;
//打印模式
/**
* S:逐笔打印:每笔明细生成一个 PDF 文件;M:批量打印:
* 所有明细生成生成到一个 PDF 文件里面
*/
private String prtmod;
//查询标记
/**
* 首次查询请输入 0,当返回报文里面有 begidx 返回时表明需要续传,
* 请将返回报文中的 begidx 值放入该字段继续请求。
*/
private String begidx;
//以下开始为非必填字段
//收方户名
private String eacnam;
//业务参考号
private String ptyref;
//最小金额
private String minamt;
//最大金额
private String maxamt;
//每批数量
/**
* 默认 1000,最大限制 1000,打印模式为 M 时表示一个文件里面包含的明细的条数,
* 打印模式为 S 时表示一次可以查询明细的条数。
*/
private String pagsiz;
}
通过“getFiledsInfo”方法很容易获取JavaBean的属性名称、值、类型
再者对JavaBean的属性挨个判空就可以了,通过下面这个方法实现
/**
* 校验javabean,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param emptyFiledList 可以为空的属性集合,没有传null
* @param message 在为空的基础上,前面添加的提示信息,没有传null
*/
public static void checkBean(Object obj, List<String> emptyFiledList, String message) {
checkParam(obj, (StringUtils.isBlank(message) ? "对象" : message) + "为空!");
//传入为空属性集合为null表示当前集合所有属性都不能为空,但为了做校验,emptyFiledList也不能为null
//在这里做校验可以减少http请求
emptyFiledList = null != emptyFiledList ? emptyFiledList : new ArrayList<>();
List<Map> objectInfoList = ReflectHelper.getFiledsInfo(obj);
for (Map objectInfo : objectInfoList) {
String name = (String) objectInfo.get("name"); //对象属性名,属性名都是字符串
//可以为空的属性不做校验
if (!emptyFiledList.contains(name)) {
//校验对象属性值是否为空
checkParam(objectInfo.get("value"), (StringUtils.isBlank(message) ? "对象的" : message + "的") + "【" + name + "】属性为空!");
}
}
}
最后做个测试
搞定,接下来可以对项目中的表单的判空做个简化了。
这是完整的工具类
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* 校验工具类
*
* @author:user
* @date: 2022-04-13 16:53
*/
public class VerifyUtil {
/**
* 校验参数是否为空
* @param obj 参数
* @param message 提示信息
*/
public static void checkParam(Object obj, String message) {
if (obj instanceof String) {
if (StringUtils.isBlank((String) obj)) throw new RuntimeException(message);
}
Optional.ofNullable(obj).orElseThrow(() -> new RuntimeException(message));
}
/**
* 校验javabean,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param nonEmptyFiledList 非空的属性集合,都可以为空传null
* @param message 在为空的基础上,前面添加的提示信息,没有传null
*/
public static void checkBeanByNonEmptyFiledList(Object obj, List<String> nonEmptyFiledList, String message) {
checkBean(obj, nonEmptyFiledList, false, message);
}
/**
* 校验javabean,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param emptyFiledList 为空的属性集合,都不可以为空传null
* @param message 在为空的基础上,前面添加的提示信息,没有传null
*/
public static void checkBeanByEmptyFiledList(Object obj, List<String> emptyFiledList, String message) {
checkBean(obj, emptyFiledList, true, message);
}
/**
* 校验javabean,所以的属性值都不能为空,传其他类型的对象可能会报错
* @param obj 校验的javabean
*/
public static void checkBean(Object obj) {
checkBean(obj, null, null, null);
}
/**
* 校验javabean,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param filedList 校验的属性集合,没有传null
*/
public static void checkBean(Object obj, List<String> filedList) {
checkBean(obj, filedList, null, null);
}
/**
* 校验javabean,所以的属性值都不能为空,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param message 在为空的基础上,前面添加的提示信息,没有传null
*/
public static void checkBean(Object obj, String message) {
checkBean(obj, null, null, message);
}
/**
* 校验javabean,传其他类型的对象可能会报错
* @param obj 校验的javabean
* @param filedList 校验的属性集合,没有传null
* @param isEmptyFiledList 是否是空字段集合,默认true
* @param message 在为空的基础上,前面添加的提示信息,没有传null
*/
public static void checkBean(Object obj, List<String> filedList, Boolean isEmptyFiledList, String message) {
checkParam(obj, (StringUtils.isBlank(message) ? "对象" : message) + "为空!");
//传入为空属性集合为null表示当前集合所有属性都不能为空,但为了做校验,emptyFiledList也不能为null
//在这里做校验可以减少http请求
filedList = null != filedList ? filedList : new ArrayList<>();
isEmptyFiledList = null != isEmptyFiledList ? isEmptyFiledList : true;
List<Map> objectInfoList = getFiledsInfo(obj);
for (Map objectInfo : objectInfoList) {
String name = (String) objectInfo.get("name"); //对象属性名,属性名都是字符串
//可以为空的属性不做校验
if (filedList.contains(name) ^ isEmptyFiledList) {
//校验对象属性值是否为空
checkParam(objectInfo.get("value"), (StringUtils.isBlank(message) ? "对象的" : message + "的") + "【" + name + "】属性为空!");
}
}
}
/**
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
*/
public static List<Map> getFiledsInfo(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
List<Map> list = new ArrayList<>();
Map<String, Object> infoMap = null;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap<>();
infoMap.put("type", fields[i].getType().toString());
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
list.add(infoMap);
}
return list;
}
/**
* 根据属性名获取属性值
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[]{
});
Object value = method.invoke(o, new Object[]{
});
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
System.out.println("(true ^ true) " + (true ^ true)); //false
System.out.println("(true ^ false) " + (true ^ false)); //true
//传入的集合中找到了元素,这个元素可以为空,不对这个元素做校验 预期false
System.out.println("(true ^ true) " + (true ^ true)); //false
//传入的集合中找到了元素,这个元素不可以为空,对这个元素做校验 预期true
System.out.println("(true ^ false) " + (true ^ false)); //true
}
}