自定义注解
带有这个注解的属性可以为空
其他的默认不能为空
/**
* @description: 参数字段可以为空的注解
* @Author: lk
* @DateTime: 2022/04/15 11:30
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldCanEmpty {
}
测试实体
/**
* @description: 测试实体
* @Author: lk
* @DateTime: 2022/04/15 11:30
*/
@Data
@AllArgsConstructor
public class TestEntity{
private String id;
private String name;
// 可以为空的属性
@FieldCanEmpty
private Integer age;
}
工具类
/**
* 实体参数为空校验
*
* @param param 参数实体
* @return 为空的属性名,逗号分隔
*/
@SneakyThrows
public static String fieldStringParamCheck(Object param) {
// 实体为空,根据是实际情况具体处理
if (param == null) {
return "实体为空";
}
StringBuilder stringBuilder = new StringBuilder();
Field[] fields = param.getClass().getDeclaredFields();
fieldFor:
for (Field field : fields) {
field.setAccessible(true);
// 带注解的可以为空
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof FieldCanEmpty) {
continue fieldFor;
}
}
// 如果属性是 String
if (field.get(param) instanceof String) {
String fieldValue = (String) field.get(param);
/*
1、属性为空
2、为空属性字符串不包含这个属性名
*/
if (StringUtils.isEmpty(fieldValue) && !stringBuilder.toString().contains(field.getName())) {
stringBuilder.append(field.getName()).append(",");
}
}
// 如果属性是 List
else if (field.get(param) instanceof List) {
List fieldList = (List) field.get(param);
if (CollectionUtils.isEmpty(fieldList) && !stringBuilder.toString().contains(field.getName())) {
stringBuilder.append(field.getName()).append(",");
}
}
// 其他类型都直接判断是否 == null
else {
if (field.get(param) == null && !stringBuilder.toString().contains(field.getName())) {
stringBuilder.append(field.getName()).append(",");
}
}
}
return stringBuilder.toString();
}
2022年7月8日:
上边的是老的版本,最近代码优化,把优化后的工具类给大家分享一下
优化后代码更加简洁易懂,希望对大家有所帮助
/**
* 判断对象里的属性是否为空
*
* @param param 参数对象
* @param paramName 参数的整体类名
* @return 为空属性的属性名字符串(逗号分隔)
*/
@SneakyThrows
public static String fieldStringParamCheck(Object param, String paramName) {
if (param == null) {
return paramName;
}
StringBuilder emptyFieldString = new StringBuilder();
for (Field field : param.getClass().getDeclaredFields()) {
field.setAccessible(true);
// 带注解的可以为空 || 重复的属性名不再收集
if (Objects.nonNull(field.getAnnotation(FieldCanEmpty.class))
|| emptyFieldString.toString().contains(field.getName())
) {
continue;
}
Object fieldObject = field.get(param);
// 其他类型的参数
boolean otherEmpty = fieldObject == null;
// 参数为 String; 1、属性为空 2、为空属性字符串不包含这个属性名
boolean stringEmpty = fieldObject instanceof String && StringUtils.isEmpty(fieldObject.toString());
// 参数属性为 list
boolean listEmpty = fieldObject instanceof List && CollectionUtils.isEmpty((List) fieldObject);
if (otherEmpty || stringEmpty || listEmpty) {
emptyFieldString.append(getFiledName(field)).append(",");
}
}
return emptyFieldString.toString();
}
/**
* 获取属性名
*/
private static String getFiledName(Field field) {
// 带有 JsonProperty 注解并且 value 有值,则不获取属性名,获取注解 value
JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
if (Objects.nonNull(jsonProperty) && StringUtils.hasText(jsonProperty.value())) {
return jsonProperty.value();
}
return field.getName();
}
示例
public static void main(String[] args) {
TestEntity testEntity = new TestEntity("123",null,null);
String s = fieldStringParamCheck(testEntity);
System.out.println(s);
}
输出:
代码为本菜鸟根据需求自制
哪里可以优化的地方,欢迎大佬指出!