校验器代码整理
This commit is contained in:
parent
65a1405d0f
commit
fac8941529
|
@ -0,0 +1,83 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import javax.validation.ConstraintTarget;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.Payload;
|
||||
import javax.validation.metadata.ConstraintDescriptor;
|
||||
import javax.validation.metadata.ValidateUnwrappedValue;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>自定义约束描述符
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/5/19
|
||||
*/
|
||||
public class CustomConstraintDescriptor<R extends Annotation> implements ConstraintDescriptor<R> {
|
||||
|
||||
private final R annotation;
|
||||
|
||||
public CustomConstraintDescriptor(R annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getGroups() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<? extends Payload>> getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintTarget getValidationAppliesTo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends ConstraintValidator<R, ?>>> getConstraintValidatorClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ConstraintDescriptor<?>> getComposingConstraints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReportAsSingleViolation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidateUnwrappedValue getValueUnwrapping() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U unwrap(Class<U> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.internal.engine.path.PathImpl;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Path;
|
||||
import javax.validation.metadata.ConstraintDescriptor;
|
||||
|
||||
/**
|
||||
* <p>校验不通过的返回值对象
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/5/19
|
||||
* <T> 需要校验的方法所在的类
|
||||
*/
|
||||
public class CustomConstraintViolation<T> implements ConstraintViolation<T> {
|
||||
|
||||
@Setter
|
||||
private String message;
|
||||
|
||||
@Setter
|
||||
private T rootBean;
|
||||
|
||||
@Setter
|
||||
private Path propertyPath;
|
||||
|
||||
@Setter
|
||||
private Object invalidValue;
|
||||
|
||||
@Setter
|
||||
private ConstraintDescriptor<?> constraintDescriptor;
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRootBean() {
|
||||
return rootBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getRootBeanClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getLeafBean() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getExecutableParameters() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExecutableReturnValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInvalidValue() {
|
||||
return invalidValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintDescriptor<?> getConstraintDescriptor() {
|
||||
return constraintDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U unwrap(Class<U> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字段值是否合法
|
||||
* @param rootBean 需要校验的方法所在的类对象
|
||||
* @param msg 校验错误信息
|
||||
* @param path 属性路径
|
||||
* @param invalidValue 校验失败的属性值
|
||||
* @param constraintDescriptor CustomConstraintDescriptor
|
||||
* @param <T> 泛型
|
||||
* @return CustomConstraintViolation
|
||||
*/
|
||||
public static <T> CustomConstraintViolation<T> of(T rootBean,
|
||||
String msg,
|
||||
String path,
|
||||
Object invalidValue,
|
||||
ConstraintDescriptor<?> constraintDescriptor) {
|
||||
CustomConstraintViolation<T> constraintViolation = new CustomConstraintViolation<>();
|
||||
constraintViolation.setMessage(msg);
|
||||
constraintViolation.setRootBean(rootBean);
|
||||
constraintViolation.setPropertyPath(PathImpl.createPathFromString(path));
|
||||
constraintViolation.setInvalidValue(invalidValue);
|
||||
constraintViolation.setConstraintDescriptor(constraintDescriptor);
|
||||
return constraintViolation;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.dashboard.framework.validator.custom.handler.ValidateHandlerHelper;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.SneakyThrows;
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 校验注解枚举
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/4/13 11:35
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ValidateAnnotationEnum {
|
||||
|
||||
NOT_NULL(NotNull.class,
|
||||
"必传!",
|
||||
(object, param) -> {
|
||||
return ObjectUtil.isNotNull(object);
|
||||
}
|
||||
),
|
||||
|
||||
NOT_EMPTY(NotEmpty.class,
|
||||
"内容不能为空!",
|
||||
(object, param) -> {
|
||||
return ObjectUtil.isNotEmpty(object);
|
||||
}
|
||||
),
|
||||
|
||||
NOT_BLANK(NotBlank.class,
|
||||
"内容需包含有效字符!",
|
||||
(object, param) -> {
|
||||
if (object instanceof String) {
|
||||
return StrUtil.isNotBlank(String.valueOf(object));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
),
|
||||
|
||||
MAX(true,
|
||||
Max.class,
|
||||
"不能超过{}",
|
||||
(object, param) -> {
|
||||
if (object instanceof Integer) {
|
||||
return param > (Integer) object;
|
||||
}
|
||||
if (object instanceof BigDecimal | object instanceof Double | object instanceof Short) {
|
||||
return new BigDecimal(String.valueOf(param)).compareTo(new BigDecimal(String.valueOf(object))) > 0;
|
||||
}
|
||||
if (object instanceof Long) {
|
||||
return param > (Long) object;
|
||||
}
|
||||
if (object instanceof Date) {
|
||||
return param > ((Date) object).getTime();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
),
|
||||
|
||||
MIN(true,
|
||||
Min.class,
|
||||
"不能小于{}",
|
||||
(object, param) -> {
|
||||
if (object instanceof Integer) {
|
||||
return param < (Integer) object;
|
||||
}
|
||||
if (object instanceof BigDecimal | object instanceof Double | object instanceof Short) {
|
||||
return new BigDecimal(String.valueOf(param)).compareTo(new BigDecimal(String.valueOf(object))) < 0;
|
||||
}
|
||||
if (object instanceof Long) {
|
||||
return param < (Long) object;
|
||||
}
|
||||
if (object instanceof Date) {
|
||||
return param < ((Date) object).getTime();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
private final boolean hadParam;
|
||||
|
||||
private final Class<? extends Annotation> annotation;
|
||||
|
||||
private final String msg;
|
||||
|
||||
private final BiFunction<Object, Long, Boolean> checkFunction;
|
||||
|
||||
ValidateAnnotationEnum(Class<? extends Annotation> annotation, String msg, BiFunction<Object, Long, Boolean> checkFunction) {
|
||||
this.hadParam = false;
|
||||
this.annotation = annotation;
|
||||
this.msg = msg;
|
||||
this.checkFunction = checkFunction;
|
||||
}
|
||||
|
||||
public String formatMsg(String fieldName, String... param) {
|
||||
if (hadParam) {
|
||||
return fieldName + MessageFormatter.arrayFormat(msg, param).getMessage();
|
||||
}
|
||||
return fieldName + msg;
|
||||
}
|
||||
|
||||
public boolean checkParam(Field field, Object object, Long... param) throws IllegalAccessException {
|
||||
if (hadParam && param != null && param.length == 1) {
|
||||
return checkFunction.apply(field.get(object), param[0]);
|
||||
}
|
||||
if (!hadParam) {
|
||||
return checkFunction.apply(field.get(object), null);
|
||||
}
|
||||
log.error("[参数校验失败!], Enum = {}, TargetClass = {}, FieldName = {}, param = {}",
|
||||
this.toString(),
|
||||
object.getClass().getSimpleName(),
|
||||
field.getName(),
|
||||
param);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public interface IfmFunction {
|
||||
|
||||
Boolean apply(Field field, Object object, Function<Object, Boolean> isValid);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
|
@ -17,6 +17,7 @@ public interface ValidateAnnotationHandler<T extends Annotation> {
|
|||
|
||||
/**
|
||||
* 获取实现类的具体的注解类对象
|
||||
* @return T
|
||||
*/
|
||||
Class<T> getAnnotation();
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 校验处理辅助类
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/4/15 9:49
|
||||
*/
|
||||
public class ValidateHandlerHelper {
|
||||
|
||||
private static Set<ValidateAnnotationHandler<?>> handlerSet = new HashSet<>(10);
|
||||
|
||||
static {
|
||||
ServiceLoader.load(ValidateAnnotationHandler.class).forEach(handlerSet::add);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验指定字段值是否合法
|
||||
* <p>
|
||||
* 这里针对集合类型字段做递归校验
|
||||
* 实现深层对象参数值校验
|
||||
*
|
||||
* @param field 字段对象
|
||||
* @param paramObject 需要校验的字段所在的对象
|
||||
* @param rootBean 需要校验的方法所在的类对象
|
||||
* @param propertyPath 属性路径
|
||||
* @param <T> 需要校验的方法所在的类
|
||||
* @return 校验结果集
|
||||
*/
|
||||
public static <T> Set<ConstraintViolation<T>> validate(Field field,
|
||||
Object paramObject,
|
||||
T rootBean,
|
||||
String propertyPath) {
|
||||
Set<ConstraintViolation<T>> result = new HashSet<>();
|
||||
|
||||
Object fieldValue;
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
fieldValue = field.get(paramObject);
|
||||
} catch (IllegalAccessException e) {
|
||||
return result;
|
||||
}
|
||||
if (fieldValue instanceof Collection) {
|
||||
Collection<?> collectionFieldValue = (Collection<?>) fieldValue;
|
||||
if (CollectionUtil.isNotEmpty(collectionFieldValue)) {
|
||||
for (Object collectionElement : collectionFieldValue) {
|
||||
Field[] fields = collectionElement.getClass().getDeclaredFields();
|
||||
for (Field collectionFieldElementField : fields) {
|
||||
result.addAll(
|
||||
validate(
|
||||
collectionFieldElementField,
|
||||
collectionElement,
|
||||
rootBean,
|
||||
propertyPath + "." + collectionFieldElementField.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomConstraintViolation<T> violation = validateField(field, paramObject, rootBean, propertyPath, fieldValue);
|
||||
if (violation != null) {
|
||||
result.add(violation);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验字段值,如果值合法返回null,不合法返回消息内容
|
||||
*
|
||||
* @param field 需要校验的字段
|
||||
* @param targetObject 字段所在的对象
|
||||
* @return 值合法返回null,不合法返回消息内容
|
||||
*/
|
||||
private static <T> CustomConstraintViolation<T> validateField(Field field,
|
||||
Object targetObject,
|
||||
T rootBean,
|
||||
String propertyPath,
|
||||
Object fieldValue) {
|
||||
Optional<ValidateAnnotationHandler<?>> handlerOptional =
|
||||
handlerSet.stream().filter(s -> s.isAnnotationPresent(field)).findFirst();
|
||||
if (handlerOptional.isPresent()) {
|
||||
String validate = handlerOptional.get().validate(field, targetObject);
|
||||
if (validate != null) {
|
||||
String fieldComment;
|
||||
if (field.isAnnotationPresent(ApiModelProperty.class)) {
|
||||
ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class);
|
||||
fieldComment = annotation.value();
|
||||
} else {
|
||||
fieldComment = field.getName();
|
||||
}
|
||||
String msg = fieldComment + validate;
|
||||
CustomConstraintDescriptor<?> customConstraintDescriptor =
|
||||
new CustomConstraintDescriptor<>(field.getAnnotation(handlerOptional.get().getAnnotation()));
|
||||
return CustomConstraintViolation.of(rootBean, msg, propertyPath, fieldValue, customConstraintDescriptor);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 最大值校验处理类
|
||||
|
@ -23,6 +25,10 @@ public class MaxHandler implements ValidateAnnotationHandler<Max> {
|
|||
|
||||
@Override
|
||||
public String validate(Max validateAnnotation, Object fieldValue) {
|
||||
if (Objects.isNull(fieldValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long value = validateAnnotation.value();
|
||||
boolean valid;
|
||||
if (fieldValue instanceof Integer) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 最小值校验处理类
|
||||
|
@ -23,6 +25,10 @@ public class MinHandler implements ValidateAnnotationHandler<Min> {
|
|||
|
||||
@Override
|
||||
public String validate(Min validateAnnotation, Object fieldValue) {
|
||||
if (Objects.isNull(fieldValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long value = validateAnnotation.value();
|
||||
boolean valid;
|
||||
if (fieldValue instanceof Integer) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>长度校验处理类
|
||||
|
@ -28,6 +30,10 @@ public class SizeHandler implements ValidateAnnotationHandler<Size> {
|
|||
|
||||
@Override
|
||||
public String validate(Size validateAnnotation, Object fieldValue) {
|
||||
if (Objects.isNull(fieldValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (fieldValue.toString().length() > validateAnnotation.max()) {
|
||||
return MessageFormatter.format(VALUE_GT, fieldValue).getMessage();
|
||||
}
|
||||
|
|
|
@ -1,283 +0,0 @@
|
|||
package cn.iocoder.dashboard.framework.validator.custom.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.internal.engine.path.PathImpl;
|
||||
|
||||
import javax.validation.*;
|
||||
import javax.validation.metadata.ConstraintDescriptor;
|
||||
import javax.validation.metadata.ValidateUnwrappedValue;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 校验处理辅助类
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/4/15 9:49
|
||||
*/
|
||||
public class ValidateHandlerHelper {
|
||||
|
||||
private static final Set<ValidateAnnotationHandler<?>> handlerSet = new HashSet<>(10);
|
||||
|
||||
/**
|
||||
* 初始化注册校验处理类
|
||||
*/
|
||||
static {
|
||||
handlerSet.add(new NotNullHandler());
|
||||
handlerSet.add(new NotEmptyHandler());
|
||||
handlerSet.add(new NotBlankHandler());
|
||||
handlerSet.add(new MaxHandler());
|
||||
handlerSet.add(new MinHandler());
|
||||
handlerSet.add(new SizeHandler());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验指定字段值是否合法
|
||||
* <p>
|
||||
* 这里针对集合类型字段做递归校验
|
||||
* 实现深层对象参数值校验
|
||||
*
|
||||
* @param field 字段对象
|
||||
* @param paramObject 需要校验的字段所在的对象
|
||||
* @param rootBean 需要校验的方法所在的类对象
|
||||
* @param propertyPath 属性路径
|
||||
* @param <T> 需要校验的方法所在的类
|
||||
* @return 校验结果集
|
||||
*/
|
||||
public static <T> Set<ConstraintViolation<T>> validate(Field field,
|
||||
Object paramObject,
|
||||
T rootBean,
|
||||
String propertyPath) {
|
||||
Set<ConstraintViolation<T>> result = new HashSet<>();
|
||||
|
||||
Object fieldValue;
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
fieldValue = field.get(paramObject);
|
||||
} catch (IllegalAccessException e) {
|
||||
return result;
|
||||
}
|
||||
if (fieldValue instanceof Collection) {
|
||||
Collection<?> collectionFieldValue = (Collection<?>) fieldValue;
|
||||
if (CollectionUtil.isNotEmpty(collectionFieldValue)) {
|
||||
for (Object collectionElement : collectionFieldValue) {
|
||||
Field[] fields = collectionElement.getClass().getDeclaredFields();
|
||||
for (Field collectionFieldElementField : fields) {
|
||||
result.addAll(
|
||||
validate(
|
||||
collectionFieldElementField,
|
||||
collectionElement,
|
||||
rootBean,
|
||||
propertyPath + "." + collectionFieldElementField.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomConstraintViolation<T> violation = validateField(field, paramObject, rootBean, propertyPath, fieldValue);
|
||||
if (violation != null) {
|
||||
result.add(violation);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验字段值,如果值合法返回null,不合法返回消息内容
|
||||
*
|
||||
* @param field 需要校验的字段
|
||||
* @param targetObject 字段所在的对象
|
||||
* @return 值合法返回null,不合法返回消息内容
|
||||
*/
|
||||
private static <T> CustomConstraintViolation<T> validateField(Field field,
|
||||
Object targetObject,
|
||||
T rootBean,
|
||||
String propertyPath,
|
||||
Object fieldValue) {
|
||||
Optional<ValidateAnnotationHandler<?>> handlerOptional =
|
||||
handlerSet.stream().filter(s -> s.isAnnotationPresent(field)).findFirst();
|
||||
if (handlerOptional.isPresent()) {
|
||||
String validate = handlerOptional.get().validate(field, targetObject);
|
||||
if (validate != null) {
|
||||
String fieldComment;
|
||||
if (field.isAnnotationPresent(ApiModelProperty.class)) {
|
||||
ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class);
|
||||
fieldComment = annotation.value();
|
||||
} else {
|
||||
fieldComment = field.getName();
|
||||
}
|
||||
String msg = fieldComment + validate;
|
||||
CustomConstraintDescriptor<?> customConstraintDescriptor =
|
||||
new CustomConstraintDescriptor<>(field.getAnnotation(handlerOptional.get().getAnnotation()));
|
||||
return CustomConstraintViolation.of(rootBean, msg, propertyPath, fieldValue, customConstraintDescriptor);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验不通过的返回值对象
|
||||
*
|
||||
* @param <T> 需要校验的方法所在的类
|
||||
*/
|
||||
public static class CustomConstraintViolation<T> implements ConstraintViolation<T> {
|
||||
|
||||
public static <T> CustomConstraintViolation<T> of(T rootBean,
|
||||
String msg,
|
||||
String path,
|
||||
Object invalidValue,
|
||||
ConstraintDescriptor<?> constraintDescriptor) {
|
||||
CustomConstraintViolation<T> constraintViolation = new CustomConstraintViolation<>();
|
||||
constraintViolation.setMessage(msg);
|
||||
constraintViolation.setRootBean(rootBean);
|
||||
constraintViolation.setPropertyPath(PathImpl.createPathFromString(path));
|
||||
constraintViolation.setInvalidValue(invalidValue);
|
||||
constraintViolation.setConstraintDescriptor(constraintDescriptor);
|
||||
return constraintViolation;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private String message;
|
||||
|
||||
@Setter
|
||||
private T rootBean;
|
||||
|
||||
@Setter
|
||||
private Path propertyPath;
|
||||
|
||||
@Setter
|
||||
private Object invalidValue;
|
||||
|
||||
@Setter
|
||||
private ConstraintDescriptor<?> constraintDescriptor;
|
||||
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRootBean() {
|
||||
return rootBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getRootBeanClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getLeafBean() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getExecutableParameters() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExecutableReturnValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInvalidValue() {
|
||||
return invalidValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintDescriptor<?> getConstraintDescriptor() {
|
||||
return constraintDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U unwrap(Class<U> type) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomConstraintDescriptor<R extends Annotation> implements ConstraintDescriptor<R> {
|
||||
|
||||
private final R annotation;
|
||||
|
||||
public CustomConstraintDescriptor(R annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getGroups() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<? extends Payload>> getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintTarget getValidationAppliesTo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends ConstraintValidator<R, ?>>> getConstraintValidatorClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ConstraintDescriptor<?>> getComposingConstraints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReportAsSingleViolation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidateUnwrappedValue getValueUnwrapping() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U unwrap(Class<U> type) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,8 @@ package cn.iocoder.dashboard.framework.validator.custom;
|
|||
* 功能说明:https://blog.csdn.net/qq_38688267/article/details/115720412
|
||||
* <p>
|
||||
* 环境搭建:
|
||||
* 1、实现{@link cn.iocoder.dashboard.framework.validator.custom.handler.ValidateAnnotationHandler}
|
||||
* 2、将实现类注册到{@link cn.iocoder.dashboard.framework.validator.custom.handler.ValidateHandlerHelper}中
|
||||
* 1、实现{@link cn.iocoder.dashboard.framework.validator.custom.ValidateAnnotationHandler}
|
||||
* 2、将实现类注册到{@link cn.iocoder.dashboard.framework.validator.custom.ValidateHandlerHelper}中
|
||||
* 3、实现全局异常拦截{@link javax.validation.ConstraintViolationException}异常
|
||||
*
|
||||
* 使用步骤:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
cn.iocoder.dashboard.framework.validator.custom.handler.MaxHandler
|
||||
cn.iocoder.dashboard.framework.validator.custom.handler.MinHandler
|
||||
cn.iocoder.dashboard.framework.validator.custom.handler.NotBlankHandler
|
||||
cn.iocoder.dashboard.framework.validator.custom.handler.NotEmptyHandler
|
||||
cn.iocoder.dashboard.framework.validator.custom.handler.NotNullHandler
|
||||
cn.iocoder.dashboard.framework.validator.custom.handler.SizeHandler
|
Loading…
Reference in New Issue