文章目录
- Pre
- 概述
- 三部曲
- Step1 搞自定义注解
- Step2 搞校验逻辑
- Step3 使用
- Step4 验证
- 附 int 类型的判断
- 源码
Pre
SpringBoot - 优雅的实现【参数校验】高级进阶
概述
接上文, Spring Validation 提供的注解基本上够用,但是复杂的校验,我们还是需要自己定义注解来实现自动校验。
举个例子: 实体类中的sex性别属性 , 只能输入 M 、 F 这2个枚举值
三部曲
Step1 搞自定义注解
package com.artisan.customvalidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
(RUNTIME)
(EnumString.List.class)
(validatedBy = EnumStringValidator.class)//标明由哪个类执行校验逻辑
public @interface EnumString {
String message() default "value not in enum values.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* @return date must in this value array
*/
String[] value();
/**
* Defines several {@link EnumString} annotations on the same element.
*
* @see EnumString
*/
({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
(RUNTIME)
@interface List {
EnumString[] value();
}
}
Step2 搞校验逻辑
package com.artisan.customvalidator;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
public class EnumStringValidator implements ConstraintValidator<EnumString, String> {
private List<String> enumStringList;
public void initialize(EnumString constraintAnnotation) {
log.info("EnumStringValidator initialize.....");
enumStringList = Arrays.asList(constraintAnnotation.value());
}
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return enumStringList.contains(value);
}
}
Step3 使用
在字段上增加注解
Step4 验证
附 int 类型的判断
package com.artisan.customvalidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author 小工匠
* @version 1.0
* @Des 扩展int枚举校验
* @mark: show me the code , change the world
*/
({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
(RUNTIME)
(EnumInteger.List.class)
(validatedBy = EnumNumberValidator.class)
public @interface EnumInteger {
String message() default "value not in enum values.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* @return date must in this value array
*/
int[] value();
/**
* Defines several {@link EnumInteger} annotations on the same element.
*
* @see EnumInteger
*/
({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
(RUNTIME)
@interface List {
EnumInteger[] value();
}
}
package com.artisan.customvalidator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
public class EnumNumberValidator implements ConstraintValidator<EnumInteger, Number> {
private List<Integer> enumStringList;
public void initialize(EnumInteger constraintAnnotation) {
enumStringList = new ArrayList<>();
int[] values = constraintAnnotation.value();
for (int value : values) {
enumStringList.add(value);
}
}
public boolean isValid(Number value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return enumStringList.contains(value.intValue());
}
}
源码
https://github.com/yangshangwei/boot2