背景: 日常开发中,会经常遇到参数校验的问题. 大量的if _ else 会使代码可读性变差,后期维护变得异常艰难. 对于开发者而言,不仅仅是单纯的功能实现.设计出简洁通熟易懂的代码更应该是开发者不可推卸的责任.
核心
/**
* @param data 校验数据
* @param cyclic 异常后是否校验后续字段
* @param joint 是否拼接属性名 name:name字段不能为空
*/
public static String valid(Object data, boolean cyclic, boolean joint) {
Class<?> aClass = data.getClass();
StringBuffer stf = new StringBuffer();
for (Field field : aClass.getDeclaredFields()) {
field.setAccessible(true);
try {
Object value = field.get(data);
// 解析属性值
Param param = parse(value);
// 获取注解信息
Annotation[] annotations = field.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
if(value == null) return field.getName() + " : " + " : 不能为空";
String name = annotation.annotationType().getSimpleName();
Parent parent = checkMap.get(name);
String message = parent.check(annotation, param);
String errorMsg = message;
// 是否拼接fieldName
if (joint && StringUtils.isNotBlank(message)) {
errorMsg = field.getName() + " : " + message + " ";
}
// 是否循环校验
if (cyclic && StringUtils.isNotBlank(message)) {
stf.append(errorMsg);
}
// 非循环校验 第一次异常直接抛出
if (!cyclic && StringUtils.isNotBlank(message)) {
return errorMsg;
}
}
return stf.toString();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
代码块
/** * 解析参数 包含 长度 大小 解析属性 */ private static Param parse(Object o) { // 参数 Param param = new Param(); if (o instanceof Number) { if (o instanceof BigDecimal) { BigDecimal bigDecimal = (BigDecimal) o; // 小数位 int scale = bigDecimal.scale(); param.setTail(scale); param.setValue(bigDecimal); param.setLength(bigDecimal.toString().length()); } else { Double value = (Double) o; BigDecimal bigDecimal = BigDecimal.valueOf(value); // 小数位 int scale = bigDecimal.scale(); param.setTail(scale); param.setValue(bigDecimal); param.setLength(bigDecimal.toString().length()); } } else { String value = (String) o; param.setLength(value.length()); } return param; }
// 策略类
static { checkMap = new HashMap(); checkMap.put("Max", new Max()); checkMap.put("Min", new Min()); }
/** * @author haizhuangbu * @date 2022/9/14 14:29 * @mark Max 具体实现 */ public class Max implements Parent { @Override public String check(Annotation annotation, Param value) { com.util.anno.Max max = (com.util.anno.Max) annotation; BigDecimal val = value.getValue(); return val.compareTo(BigDecimal.valueOf(max.VALUE())) > 0 ? max.MESSAGE() : ""; }