SpringBoot Validation校验参数
目录
依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
使用Spring boot 框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
约束性注解(简单)说明
注解 | 功能 |
---|---|
@AssertFalse | 可以为null,如果不为null的话必须为false |
@AssertTrue | 可以为null,如果不为null的话必须为true |
@DecimalMax | 设置不能超过最大值 |
@DecimalMin | 设置不能超过最小值 |
@Digits | 设置必须是数字且数字整数的位数和小数的位数必须在指定范围内 |
@Future | 日期必须在当前日期的未来 |
@Past | 日期必须在当前日期的过去 |
@Max | 最大不得超过此最大值 |
@Min | 最大不得小于此最小值 |
@NotNull | 不能为null,可以是空 |
@Null | 必须为null |
@Pattern | 必须满足指定的正则表达式 |
@Size | 集合、数组、map等的size()值必须在指定范围内 |
必须是email格式 | |
@Length | 长度必须在指定范围内 |
@NotBlank | 字符串不能为null,字符串trim()后也不能等于“” |
@NotEmpty | 不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“” |
@Range | 值必须在指定范围内 |
@URL | 必须是一个URL |
类型 | 注解 | 功能 |
---|---|---|
空检查 | @Null | 必须为null |
@NotNull | 不能为null,可以是空 | |
@NotBlank | 字符串不能为null,字符串trim()后也不能等于“” | |
@NotEmpty | 不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“” | |
Booelan检查 | @AssertFalse | 可以为null,如果不为null的话必须为false |
@AssertTrue | 可以为null,如果不为null的话必须为true | |
长度检查 | @Size(min=, max=) | 对象(Array,Collection,Map,String)的长度必须在指定范围内 |
@Length(min=, max=) | String长度必须在指定范围内 | |
日期检查 | @Past | 日期(Date 和 Calendar 对象)必须在当前日期的过去 |
@Future | 日期(Date 和 Calendar 对象)必须在当前日期的未来 | |
@Pattern | String 对象必须满足指定的正则表达式 | |
数值检查 | 建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"" , Integer为null | |
@Min | 验证 Number 和 String 对象是否大等于指定的值 | |
@Max | 验证 Number 和 String 对象是否小等于指定的值 | |
@DecimalMin | 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度 | |
@DecimalMax | 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度 | |
@Digits | 验证 Number 和 String 的构成是否合法 | |
@Digits(integer=,fraction=) | 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度 | |
@Range(min=, max=) | 检查数字是否介于min和max之间 | |
其他检查 | @Valid | 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证) |
@CreditCardNumber | 信用卡验证 | |
验证是否是邮件地址,如果为null,不进行验证,算通过验证 | ||
@ScriptAssert | @ScriptAssert(lang= ,script=, alias=) | |
@URL | @URL(protocol=,host=, port=,regexp=, flags=) 验证是否是URL地址 |
自定义注解
1. 创建自定义注解
-
@Constraint:校验此注解的校验器类
-
定义一个注解,由于要使用ConstraintValidator进行校验,groups 和 payload这两个参数是必要的。
-
groups可以指定注解使用的场景,一个实体类可能会在多个场合有使用,如插入,删除等。通过groups可以指定该注解在插入/删除的环境下生效。
-
payload往往对bean进行使用。
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {MyParamValidValidator.class})
@Documented
public @interface MyParamValid {
/**
* 指定param参数范围
* @return
*/
String[] value() default {};
String message() default "param is not valid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2. 编写校验器 实现注解的校验
注解约束实现了ConstraintValidator接口,第一个参数是自定义注解类,第二个是要校验的数据类型
import java.util.stream.Stream;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class MyParamValidValidator implements ConstraintValidator<MyParamValid, String> {
private String[] values;
@Override
public void initialize(MyParamValid constraintAnnotation) {
this.values = constraintAnnotation.value();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 当值为空时,校验通过
if (value == null) {
return true;
}
return Stream.of(values).filter(x -> x.equals(value)).findFirst().isPresent();
}
}
3. 自定义注解的使用
@Data
public class TestValidatorDTO {
/** 参数校验测试 */
@MyParamValid(value = {"red", "yellow", "blue"})
private String color;
}
@RequestMapping("/dto")
public String valid(@Valid TestValidatorDTO dto) {
return "dto.color = " + dto.getColor();
}
枚举类型校验
1. 创建枚举类
public enum ColorEnum {
RED("red", "红色"),
YELLOW("yellow", "黄色"),
BLUE("blue", "蓝色");
private String color;
private String desc;
private ColorEnum(String color, String desc) {
this.color = color;
this.desc = desc;
}
public String getColor() {
return color;
}
public String getDesc() {
return desc;
}
private static Map<String, ColorEnum> TYPE_MAP = new HashMap<String, ColorEnum>();
static {
for (ColorEnum typeEnum : ColorEnum.values()) {
TYPE_MAP.put(typeEnum.getColor(), typeEnum);
}
}
public static ColorEnum from(String color) {
return TYPE_MAP.get(color);
}
}
2. 创建自定义注解&编写校验器
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = EnumValidatorConstraint.EnumValidator.class)
public @interface EnumValidatorConstraint {
String message() default "value is not valid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<?> enumClass();
Class<?> valueClass();
// 编写校验器
class EnumValidator implements ConstraintValidator<EnumValidatorConstraint, Object>{
private static final String FROM_METHOD = "from";
private Class<?> enumClass;
private Class<?> valueClass;
@Override
public void initialize(EnumValidatorConstraint constraintAnnotation) {
this.enumClass = constraintAnnotation.enumClass();
this.valueClass = constraintAnnotation.valueClass();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
// 当值为空时,校验通过
if (value == null) {
return true;
}
// 配置为空,校验失败
if (enumClass == null || !enumClass.isEnum()) {
return false;
}
try {
Method method = this.enumClass.getMethod(FROM_METHOD, valueClass);
if (method == null) {
return false;
}
Object resultEnum = method.invoke(null, value);
return resultEnum != null;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
}
3. 测试
@Data
public class TestValidatorDTO {
/** 参数校验测试 */
@MyParamValid(value = {"red", "yellow", "blue"})
private String color;
@EnumValidatorConstraint(enumClass = ColorEnum.class, valueClass = String.class)
private String color2;
@EnumValidatorConstraint(enumClass = OptionTypeEnum.class, valueClass = int.class)
private int optionType;
}