SpringBoot使用JSR303校验数据

JSR303是java提供的一套用来校验数据的规范

SpringBoot使用JSR303校验数据

javax.validation.constraints

使用方式:

  1. 在Entity实体类上加上相应的注解,并定义自定义message(错误提示)
  2. @Valid启用校验

数据验证不通过:

  • 状态码:400

可以在需要校验的对象后面紧跟一个BindingResult对象

常用注解:

  • @NotNull不能为空
  • @NotEmpty不能为空串
  • @Min(value = "")可在value中规定最小值
  • @Max(value = "")可在value中规定最大值
  • @Url*(不在javax.validation.constraints包中)验证是否是一个合法的URL地址
  • @Email验证时否是一个合法的邮箱地址
  • @Pattern(regexp="[正则表达式]")使用自定义的正则表达式验证数据

分组校验

可以使用满足JSR303规范的注解上加上groups属性即可实现分组校验

❕需要新建Interface来表明group的类型,比如AddGroup,UpdateUpdate

public interface AddGroup{}

	/**
	 * 品牌id
	 */
	@NotBlank(message = "修改时必须携带id属性", groups = {UpdateGroup.class})
	@Null(message = "添加时不能携带id属性", groups = {AddGroup.class})
	@TableId
	private Long brandId;
	/**
	 * 品牌名
	 */
	@NotEmpty(message = "品牌名不能为空", groups = {UpdateGroup.class, AddGroup.class})
	private String name;
	/**
	 * 品牌logo地址
	 */
	@NotBlank(message = "添加时必须携带logo地址", groups = {AddGroup.class})
	@URL(message = "logo必须时一个合法的URL字符串", groups = {UpdateGroup.class, AddGroup.class})
	private String logo;
	/**
	 * 介绍
	 */
	@NotEmpty(message = "介绍不能为空", groups = {AddGroup.class})
	private String descript;
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	@NotNull(message = "显示状态不能为空", groups = {AddGroup.class})
	private Integer showStatus;
	/**
	 * 检索首字母
	 */
	@NotBlank(message = "检索首字母不能为空", groups = {AddGroup.class})
	@Pattern(regexp = "^[A-z]$")
	private String firstLetter;
	/**
	 * 排序
	 */
	@Min(value = 0, message = "排序必须是大于0的整数", groups = {AddGroup.class, UpdateGroup.class})
    @NotNull(groups = {AddGroup.class})
	private Integer sort;

在使用这些数据校验时,可以使用Spring提供的的@Validated注解,来确定要启用的分组

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand){
		brandService.save(brand);

        return R.ok();
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
		brandService.updateById(brand);

        return R.ok();
    }

自定义数据校验注解

javax.validation.constraints包、Spring框架、Mybatis给我们提供了很多的数据校验的框架,但是如果我们有我们自己的业务逻辑需要用到指定的数据校验注解时,就可以自定义校验的注解

比如,我们现在有一个需求,showStatus属性只能是一个0或者1的数字,不然就会报错

@SpecifiedValue(specified = {0, 1})
private Integer showStatus;

1. 先创建注解

更具JSR303规范的定义,一个满足规范的数据检验注解需要三个原注解

  • @Constraint(validatedBy = { })指定专用的校验器
  • @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) 注解可以使用的位置
  • @Retention(RUNTIME)注解在何时生效

JSR303规范还要求一个校验注解的属性必须包含:

  • String message() default "{....message}"; 错误信息
  • Class<?>[] groups() default { };校验所属组
  • Class<? extends Payload>[] payload() default { };
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface SpecifiedValue {

    String message() default "{com.geekfaraj.common.valid.SpecifiedValue.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    int[] specified() default { };
}

2. 创建自定义校验器

观察Constraint注解的源码

Class<? extends ConstraintValidator<?, ?>>[] validatedBy();

可以看到validatedBy字段需要提供的是一个实现了ConstraintValidator接口的类的类对象

所以我们就创建一个类SpecifiedValueValidator去实现ConstraintValidator接口,并且编写业务逻辑

public class SpecifiedValueValidator implements ConstraintValidator<SpecifiedValue, Integer> {

    private Set<Integer> set = new HashSet<>();
    
    @Override
    public void initialize(SpecifiedValue constraintAnnotation) {
        int[] specified = constraintAnnotation.specified();
        for (int anInt : specified){
            set.add(anInt);
        }
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return set.contains(value);
    }
}

最后要将自己写的校验器写到自定义注解的@Constraint原注解的validatedBy字段中

@Constraint(validatedBy = { SpecifiedValueValidator.class })

3. 自定义默认错误信息

数据校验错误的错误信息默认会去配置文件ValidationMessages.properties中寻找,所以我们可以在resource中新建这个文件,然后添加属性

com.geekfaraj.common.valid.SpecifiedValue.message=必须提交指定的值
posted @ 2021-01-29 11:45  FarajMujey  阅读(140)  评论(0)    收藏  举报