feat: 实现校验支持
This commit is contained in:
parent
45b0d7abb5
commit
56863ad880
@ -1,32 +1,99 @@
|
|||||||
package com.flyfish.framework.beans.enums;
|
package com.flyfish.framework.beans.enums;
|
||||||
|
|
||||||
import com.flyfish.framework.beans.meta.BeanProperty;
|
|
||||||
import com.flyfish.framework.beans.meta.BeanValidation;
|
import com.flyfish.framework.beans.meta.BeanValidation;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.hibernate.validator.constraints.Currency;
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
import org.springframework.core.annotation.MergedAnnotation;
|
import org.springframework.core.annotation.MergedAnnotation;
|
||||||
|
import org.springframework.core.annotation.MergedAnnotations;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.*;
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验候选元
|
* 校验候选元
|
||||||
|
* 提供工厂方法进行构建
|
||||||
*
|
*
|
||||||
* @author wangyu
|
* @author wangyu
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum ValidationCandidate {
|
public enum ValidationCandidate {
|
||||||
|
|
||||||
REQUIRED((annotation, property) -> new BeanValidation().setRequired(true).setMessage(annotation.getString("message")),
|
// 必填
|
||||||
Arrays.asList(NotBlank.class, NotEmpty.class, NotNull.class));
|
REQUIRED((annotation, validation) -> validation.setRequired(true), NotBlank.class, NotEmpty.class, NotNull.class),
|
||||||
|
// 正则表达式
|
||||||
|
PATTERN((annotation, validation) -> validation.setPattern(annotation.getString("regexp")), Pattern.class),
|
||||||
|
// 必须为null
|
||||||
|
NULL((annotation, validation) -> validation.setValidator("null"), Null.class),
|
||||||
|
// 长度验证
|
||||||
|
LEN((annotation, validation) -> {
|
||||||
|
int min = annotation.getInt("min");
|
||||||
|
int max = annotation.getInt("max");
|
||||||
|
if (min == max) {
|
||||||
|
validation.setLen(max);
|
||||||
|
} else {
|
||||||
|
validation.setMin(min).setMax(max);
|
||||||
|
}
|
||||||
|
}, Length.class, Size.class, Range.class),
|
||||||
|
// 最小长度
|
||||||
|
MIN((annotation, validation) -> validation.setMax(annotation.getInt("value")), Min.class),
|
||||||
|
// 最大长度
|
||||||
|
MAX((annotation, validation) -> validation.setMin(annotation.getInt("value")), Max.class),
|
||||||
|
// 电子邮件
|
||||||
|
EMAIL((annotation, validation) -> validation.setType("email"), Email.class),
|
||||||
|
// URL地址
|
||||||
|
URL_ADDRESS((annotation, validation) -> validation.setType("url"), URL.class),
|
||||||
|
// 数字
|
||||||
|
DIGITS((annotation, validation) -> validation.setType("number").setValidator("digits")
|
||||||
|
.prop("integer", annotation.getInt("integer")).prop("fraction", annotation.getInt("fraction")),
|
||||||
|
Digits.class),
|
||||||
|
// 日期
|
||||||
|
DATE((annotation, validation) -> validation.setValidator("date").prop("type", annotation.getType().getSimpleName()),
|
||||||
|
Future.class, FutureOrPresent.class, Past.class, PastOrPresent.class),
|
||||||
|
// 负数正数
|
||||||
|
NATURE((annotation, validation) -> validation.setType("number").setValidator("nature")
|
||||||
|
.prop("type", annotation.getType().getSimpleName()),
|
||||||
|
Negative.class, NegativeOrZero.class, Positive.class, PositiveOrZero.class),
|
||||||
|
// 货币
|
||||||
|
CURRENCY((annotation, validation) -> validation.setValidator("currency"), Currency.class);
|
||||||
|
|
||||||
private final BiFunction<MergedAnnotation<?>, BeanProperty, BeanValidation> mapper;
|
private final BiConsumer<MergedAnnotation<?>, BeanValidation> mapper;
|
||||||
|
|
||||||
private final List<Class<? extends Annotation>> annotations;
|
private final List<Class<? extends Annotation>> annotations;
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
ValidationCandidate(BiConsumer<MergedAnnotation<?>, BeanValidation> mapper,
|
||||||
|
Class<? extends Annotation>... annotations) {
|
||||||
|
this.mapper = mapper;
|
||||||
|
this.annotations = Arrays.asList(annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过合并注解集合匹配
|
||||||
|
*
|
||||||
|
* @param annotations 注解集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static List<BeanValidation> produce(MergedAnnotations annotations) {
|
||||||
|
return Arrays.stream(values()).flatMap(candidate -> candidate.annotations.stream().map(annotations::get)
|
||||||
|
.filter(MergedAnnotation::isPresent).map(candidate::produce)
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生产校验规则
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public BeanValidation produce(MergedAnnotation<?> annotation) {
|
||||||
|
BeanValidation validation = new BeanValidation().setMessage(annotation.getString("message"));
|
||||||
|
mapper.accept(annotation, validation);
|
||||||
|
return validation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.flyfish.framework.beans.meta;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.flyfish.framework.annotations.Properties;
|
import com.flyfish.framework.annotations.Properties;
|
||||||
import com.flyfish.framework.annotations.*;
|
import com.flyfish.framework.annotations.*;
|
||||||
|
import com.flyfish.framework.beans.enums.ValidationCandidate;
|
||||||
import com.flyfish.framework.domain.base.Qo;
|
import com.flyfish.framework.domain.base.Qo;
|
||||||
import com.flyfish.framework.domain.base.Vo;
|
import com.flyfish.framework.domain.base.Vo;
|
||||||
import com.flyfish.framework.utils.ReflectionUtils;
|
import com.flyfish.framework.utils.ReflectionUtils;
|
||||||
@ -17,7 +18,6 @@ import org.apache.commons.lang3.reflect.FieldUtils;
|
|||||||
import org.apache.commons.lang3.reflect.TypeUtils;
|
import org.apache.commons.lang3.reflect.TypeUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
|
||||||
import org.springframework.core.annotation.MergedAnnotation;
|
import org.springframework.core.annotation.MergedAnnotation;
|
||||||
import org.springframework.core.annotation.MergedAnnotations;
|
import org.springframework.core.annotation.MergedAnnotations;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
@ -128,7 +128,7 @@ public class BeanProperty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 优雅的处理校验
|
// 优雅的处理校验
|
||||||
parseValidation(property, annotations);
|
property.setValidation(ValidationCandidate.produce(annotations));
|
||||||
} else if (strict) {
|
} else if (strict) {
|
||||||
property.setReadonly(true);
|
property.setReadonly(true);
|
||||||
return property;
|
return property;
|
||||||
@ -328,15 +328,6 @@ public class BeanProperty {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析验证机制
|
|
||||||
* @param property 属性
|
|
||||||
* @param annotations 注解们
|
|
||||||
*/
|
|
||||||
private static void parseValidation(BeanProperty property, MergedAnnotations annotations) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置当前对象的键值属性
|
* 设置当前对象的键值属性
|
||||||
*
|
*
|
||||||
|
@ -1,17 +1,8 @@
|
|||||||
package com.flyfish.framework.beans.meta;
|
package com.flyfish.framework.beans.meta;
|
||||||
|
|
||||||
import org.hibernate.validator.constraints.Currency;
|
|
||||||
import org.hibernate.validator.constraints.Length;
|
|
||||||
import org.hibernate.validator.constraints.Range;
|
|
||||||
import org.hibernate.validator.constraints.URL;
|
|
||||||
|
|
||||||
import javax.validation.constraints.*;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 枚举常用的bean属性
|
* 枚举常用的bean属性
|
||||||
|
*
|
||||||
* @author wangyu
|
* @author wangyu
|
||||||
*/
|
*/
|
||||||
public interface BeanProps {
|
public interface BeanProps {
|
||||||
@ -26,11 +17,4 @@ public interface BeanProps {
|
|||||||
String LAYOUT_HALF = "half";
|
String LAYOUT_HALF = "half";
|
||||||
|
|
||||||
String LAYOUT_TABLE = "table";
|
String LAYOUT_TABLE = "table";
|
||||||
|
|
||||||
List<Class<? extends Annotation>> VALIDATION_TYPES = Arrays.asList(
|
|
||||||
NotBlank.class, NotEmpty.class, NotNull.class, Null.class, Email.class, Digits.class, Future.class,
|
|
||||||
FutureOrPresent.class, Past.class, PastOrPresent.class, Pattern.class, Max.class, Min.class,
|
|
||||||
Negative.class, NegativeOrZero.class, Positive.class, PositiveOrZero.class, Size.class,
|
|
||||||
Length.class, Range.class, URL.class, Currency.class
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,13 @@ package com.flyfish.framework.beans.meta;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 智能验证实体
|
* 智能验证实体
|
||||||
* 封装了通用验证框架和前端校验框架的适配,支持严格统一验证
|
* 封装了通用验证框架和前端校验框架的适配,支持严格统一验证
|
||||||
|
*
|
||||||
* @author wangyu
|
* @author wangyu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ -15,6 +19,9 @@ public class BeanValidation {
|
|||||||
// 是否必需
|
// 是否必需
|
||||||
private Boolean required;
|
private Boolean required;
|
||||||
|
|
||||||
|
// 类型
|
||||||
|
private String type;
|
||||||
|
|
||||||
// 验证文案
|
// 验证文案
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
@ -23,4 +30,21 @@ public class BeanValidation {
|
|||||||
|
|
||||||
// 验证长度
|
// 验证长度
|
||||||
private int len;
|
private int len;
|
||||||
|
|
||||||
|
// 验证最小长度
|
||||||
|
private int min;
|
||||||
|
|
||||||
|
// 验证最大长度
|
||||||
|
private int max;
|
||||||
|
|
||||||
|
// 内建的验证器
|
||||||
|
private String validator;
|
||||||
|
|
||||||
|
// 额外的选项
|
||||||
|
private Map<String, Object> properties = new HashMap<>();
|
||||||
|
|
||||||
|
public BeanValidation prop(String key, Object value) {
|
||||||
|
properties.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user