函数式接口
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
缓存类NonNullCache
@Data
@Accessors(chain = true)
public class NonNullCache implements Serializable {
private String fieldAlias;
private Class<?> fieldClass;
}
校验基础抽象类 ValidateWrapper
public abstract class ValidateWrapper<T> {
protected Map<String, NonNullCache> nonNullCacheMap = Maps.newHashMapWithExpectedSize(6);
public abstract T getEntity();
public Map<String, NonNullCache> getNonNullCacheMap() {
return nonNullCacheMap;
}
}
比较接口Judge
public interface Judge<C, F> extends Serializable {
/**
* @param field 字段
* @param fieldAlias 字段别名
*
* @return 子类
*/
C notNull(F field, String fieldAlias);
/**
* @param field 字段
* @param fieldAlias 字段别名
*
* @return 子类
*/
C notEmpty(F field, String fieldAlias);
/**
* @param field 字段
* @param fieldAlias 字段别名
*
* @return 子类
*/
C notBlank(F field, String fieldAlias);
}
AbstractValidateWrapper
public abstract class AbstractValidateWrapper<T, F, C extends AbstractValidateWrapper<T, F, C>>
extends ValidateWrapper<T> implements Judge<C, F> {
/**
* 子类类型
*/
protected final C typedThis = (C) this;
/**
* 对应对象
*/
private T entity;
/**
* 对应对象额类型
*/
private Class<T> entityClass;
@Override
public C notNull(F field, String fieldAlias) {
return typedThis;
}
@Override
public C notEmpty(F field, String fieldAlias) {
return typedThis;
}
@Override
public C notBlank(F field, String fieldAlias) {
return typedThis;
}
public Class<T> getEntityClass() {
if (Objects.isNull(entityClass) && Objects.nonNull(entity)) {
entityClass = (Class<T>) entity.getClass();
}
return entityClass;
}
public C setEntityClass(Class<T> entityClass) {
if (Objects.nonNull(entityClass)) {
this.entityClass = entityClass;
}
return typedThis;
}
public C setEntity(T entity) {
this.entity = entity;
return typedThis;
}
@Override
public T getEntity() {
return entity;
}
}
AbstractLambdaValidateWrapper
public abstract class AbstractLambdaValidateWrapper<T, C extends AbstractLambdaValidateWrapper<T, C>>
extends AbstractValidateWrapper<T, SFunction<T, ?>, C> {
/**
* 子类类型
*/
protected final C typedThis = (C) this;
@Override
public C notNull(SFunction<T, ?> field, String fieldAlias) {
initNonNullCacheMap(field, fieldAlias);
return typedThis;
}
@Override
public C notEmpty(SFunction<T, ?> field, String fieldAlias) {
initNonNullCacheMap(field, fieldAlias);
return typedThis;
}
@Override
public C notBlank(SFunction<T, ?> field, String fieldAlias) {
initNonNullCacheMap(field, fieldAlias);
return typedThis;
}
private void initNonNullCacheMap(SFunction<T, ?> field, String fieldAlias) {
String propertyName = getField(field);
if (!nonNullCacheMap.containsKey(propertyName)) {
nonNullCacheMap.put(propertyName, new NonNullCache().setFieldAlias(fieldAlias).setFieldClass(LambdaUtils.getMetaClass(field)));
}
}
private String getField(SFunction<T, ?> field) {
SerializedLambda serializedLambda = LambdaUtils.extract(field);
return LambdaUtils.methodToProperty(serializedLambda.getImplMethodName());
}
}
LambdaValidateWrapper
public class LambdaValidateWrapper<T> extends AbstractLambdaValidateWrapper<T, LambdaValidateWrapper<T>> {
public LambdaValidateWrapper(T entity) {
super.setEntity(entity);
}
}
lamda工具类 LambdaUtils
public final class LambdaUtils {
/**
* @param func 需要解析的 lambda 对象
* @param <T> 类型,被调用的 Function 对象的目标类型
*
* @return 返回解析后的结果
*/
@SneakyThrows
public static <T> SerializedLambda extract(SFunction<T, ?> func) {
Method method = func.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
return (SerializedLambda) method.invoke(func);
}
public static String methodToProperty(String name) {
if (name.startsWith("is")) {
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {
name = name.substring(3);
} else {
throw new LincUtilException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
}
if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
}
return name;
}
@SneakyThrows
public static <T> Class<?> getMetaClass(SFunction<T, ?> func) {
SerializedLambda serializedLambda = extract(func);
// ()Ljava/util/List;
String implMethodSignature = serializedLambda.getImplMethodSignature();
return Class.forName(implMethodSignature.replace("()L", "").replaceAll("/", ".").replace(";", ""));
}
}
自定义异常 LincUtilException
public class LincUtilException extends RuntimeException{
private static final long serialVersionUID = 1L;
public LincUtilException(String message) {
super(message);
}
public LincUtilException(Throwable throwable) {
super(throwable);
}
public LincUtilException(String message, Throwable throwable) {
super(message, throwable);
}
}
自定义异常工具 LincExceptionUtil
public class LincExceptionUtil {
/**
* 重载的方法
*
* @param t 异常
*
* @return 返回异常
*/
public static LincUtilException lue(Throwable t) {
return new LincUtilException(t);
}
/**
* 重载的方法
*
* @param msg 消息
*
* @return 返回异常
*/
public static LincUtilException lue(String msg, Object... params) {
return new LincUtilException(String.format(msg, params));
}
/**
* 返回一个新的异常,统一构建,方便统一处理
*
* @param msg 消息
* @param t 异常信息
*
* @return 返回异常
*/
public static LincUtilException lue(String msg, Throwable t, Object... params) {
return new LincUtilException(String.format(msg, params), t);
}
public static void throwLue(boolean condition, String msg, Object... params) {
if (condition) {
throw lue(msg, params);
}
}
}
核心工具类 AssertUtil
@Slf4j
public class AssertUtil {
/**
* 用法
* List<Role> roleList = new ArrayList<>(0);
* User user = new User().setRoleList(roleList).setName("");
* AssertUtil.validate(new LambdaValidateWrapper<>(user)
* .notNull(User::getIsMarried, "结婚状态")
* .notNull(User::getId, "ID")
* .notBlank(User::getName, "姓名")
* .notNull(User::getRole, "角色信息")
* .notEmpty(User::getRoleList, "角色列表")
*
* @param wrapper
* @param <T>
*/
public static <T> void validate(ValidateWrapper<T> wrapper) {
T t = wrapper.getEntity();
Map<String, NonNullCache> nonNullCacheMap = wrapper.getNonNullCacheMap();
if (nonNullCacheMap.isEmpty()) {
log.info("没有需要校验的参数,请添加需要校验的参数");
return;
}
List<Field> nullFields = new ArrayList<>();
StringBuilder sb = new StringBuilder();
Stream.of(t.getClass().getDeclaredFields()).filter(f -> Objects.nonNull(nonNullCacheMap.get(f.getName()))).forEach(f -> {
f.setAccessible(true);
try {
Object o = f.get(t);
NonNullCache nonNullCache = nonNullCacheMap.get(f.getName());
Class<?> fieldClass = nonNullCache.getFieldClass();
if (fieldClass.equals(String.class)) {
if (StringUtils.isBlank((String) o)) {
buildReturnInfo(nonNullCacheMap, nullFields, sb, f);
}
} else if (fieldClass.equals(List.class)) {
if (CollectionUtils.isEmpty((List<?>) o)) {
buildReturnInfo(nonNullCacheMap, nullFields, sb, f);
}
} else if (fieldClass.equals(Map.class)) {
Map<?, ?> tmp = (Map<?, ?>) o;
if (tmp == null || tmp.size() == 0) {
buildReturnInfo(nonNullCacheMap, nullFields, sb, f);
}
} else {
if (Objects.isNull(o)) {
buildReturnInfo(nonNullCacheMap, nullFields, sb, f);
}
}
} catch (IllegalAccessException ex) {
throw LincExceptionUtil.lue("对象参数校验反射异常:%s", ex.getMessage());
}
});
if (CollectionUtils.isEmpty(nullFields)) {
return;
}
sb.deleteCharAt(sb.lastIndexOf(",")).append("不能为空");
throw LincExceptionUtil.lue(sb.toString());
}
private static void buildReturnInfo(Map<String, NonNullCache> nonNullCacheMap, List<Field> nullFields, StringBuilder sb, Field f) {
NonNullCache nonNullCache = nonNullCacheMap.get(f.getName());
sb.append(nonNullCache.getFieldAlias()).append(",");
nullFields.add(f);
}
}
用法
notNull(字段名,字段别名)---->对象
notBlank(字段名,字段别名)---->字符串
notEmpty(字段名,字段别名)–>集合
List<Role> roleList = new ArrayList<>(0);
User user = new User().setRoleList(roleList).setName("");
AssertUtil.validate(new LambdaValidateWrapper<>(user)
.notNull(User::getIsMarried, "结婚状态")
.notNull(User::getId, "ID")
.notBlank(User::getName, "姓名")
.notNull(User::getRole, "角色信息")
.notEmpty(User::getRoleList, "角色列表")
异常信息是:
ID,姓名不能为空 类似这种