一个像Stream一样使用的数据校验工具
- 使用方式
新建一个类或者接口,在类或者接口上添加@Validator注解,注解中添加需要校验的类,编译后会自动生成以校验类为前缀,以被注解的类名为后缀的校验类,
packagecn.whlit.framework;
importcn.whlit.framework.domain.Item;
importcn.whlit.framework.processor.Validator;
@Validator(Item.class)
publicinterfaceValidators {
}被校验类-Item
packagecn.whlit.framework.domain;
importjava.util.List;
publicclassItem {
privateIntegerid;
privateLongnumber;
privateStringname;
privateList<String> tags;
privateList<Item> children;
publicIntegergetId() {
returnid;
}
publicvoidsetId(Integerid) {
this.id = id;
}
publicLonggetNumber() {
returnnumber;
}
publicvoidsetNumber(Longnumber) {
this.number = number;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name = name;
}
publicList<String> getTags() {
returntags;
}
publicvoidsetTags(List<String> tags) {
this.tags = tags;
}
publicList<Item> getChildren() {
returnchildren;
}
publicvoidsetChildren(List<Item> children) {
this.children = children;
}
}生成的类是位于项目的target/generated-sources/annotations目录下,包名是被注解的类所在包名,可以添加多个被注解的类进行配置,需要校验的类只能在一个@Validator
注解中配置,重复配置可能生成的类会出现不可预料的错误。
生成的校验类-ItemValidators
packagecn.whlit.framework;
importcn.whlit.framework.domain.Item;
importcn.whlit.framework.validate.AbstractValidator;
importcn.whlit.framework.validate.CollectionValidator;
importcn.whlit.framework.validate.IntegerValidator;
importcn.whlit.framework.validate.LongValidator;
importcn.whlit.framework.validate.StringValidator;
importcn.whlit.framework.validate.Validate;
importjava.lang.Override;
importjava.lang.String;
importjava.util.function.BiConsumer;
importjava.util.function.Consumer;
publicclassItemValidatorsextendsAbstractValidator<ItemValidators> {
privatefinalItemval;
privatefinalStringpath;
publicItemValidators(Itemval, Stringpath, BiConsumer<ResultCode, Validate> handler) {
super(handler);
this.val = val;
this.path = path;
}
@OverridepublicItemgetVal() {
returnval;
}
@OverridepublicStringgetPath() {
returnpath;
}
@OverridepublicItemValidatorsgetSelf() {
returnthis;
}
publicstaticItemValidatorsof(Itemval, BiConsumer<ResultCode, Validate> handler) {
returnnewItemValidators(val, "", handler);
}
ItemValidatorsid(Consumer<IntegerValidator> consumer) {
if (!isValid()) {
returngetSelf();
}
consumer.accept(newIntegerValidator(val.getId(), splicingPath("id"), handler));
returnthis;
}
ItemValidatorsnumber(Consumer<LongValidator> consumer) {
if (!isValid()) {
returngetSelf();
}
consumer.accept(newLongValidator(val.getNumber(), splicingPath("number"), handler));
returnthis;
}
ItemValidatorsname(Consumer<StringValidator> consumer) {
if (!isValid()) {
returngetSelf();
}
consumer.accept(newStringValidator(val.getName(), splicingPath("name"), handler));
returnthis;
}
publicItemValidatorstags(Consumer<CollectionValidator<StringValidator, String>> consumer) {
if (!isValid()) {
returngetSelf();
}
consumer.accept(newCollectionValidator<StringValidator, String>(val.getTags(), splicingPath("tags"), handler, (e, p) -> newStringValidator(e, p, handler)));
returnthis;
}
publicItemValidatorschildren(Consumer<CollectionValidator<ItemValidators, Item>> consumer) {
if (!isValid()) {
returngetSelf();
}
consumer.accept(newCollectionValidator<ItemValidators, Item>(val.getChildren(), splicingPath("children"), handler, (e, p) -> newItemValidators(e, p, handler)));
returnthis;
}
}
- 使用校验类
publicclassMain {
publicstaticvoidmain(String[] args) {
Itemitem = newItem();
item.setId(1);
item.setName("item");
item.setChildren(List.of(newItem()));
ItemValidators.of(item, (resultCode, validate) -> {
// 处理结果,只要是不符合的情况都会调用这个处理逻辑System.out.println(String.format("result: %s, path: [%s], value: %s",
resultCode.getMsg(), validate.getPath(), validate.getVal()));
})
// 校验item本身的属性
.id(id -> id.notNull())
.name(name -> name.notEmpty())
// 校验集合类型的属性
.children(children ->
// 集合类型这个属性本身的校验children.notNull()
// 使用forEach遍历集合的每一个元素,消费的元素为集合元素对应的校验器
.forEach(childItem ->
childItem.notNull()
.id(id -> id.notNull())
.name(name -> name.notEmpty())
)
).tags(tags ->
tags.notNull()
.forEach(tag ->
tag.notEmpty()
)
);
}
}校验结果
result: 参数不能为NULL, path: [children[0].id], value: null
result: 参数不能为NULL, path: [children[0].name], value: null
result: 参数不能为空, path: [children[0].name], value: null
result: 参数不能为NULL, path: [tags], value: null