设为首页 加入收藏

TOP

使用 SpringBoot 进行优雅的数据验证(五)
2023-08-26 21:11:14 】 浏览:106
Tags:使用 SpringBoot
quot;; // 分组 Class[] groups() default {}; // 负载 Class[] payload() default {}; }

实现 ConstraintValidator 接口编写约束校验器

public class EncryptIdValidator implements ConstraintValidator<EncryptId, String> {

    private static final Pattern PATTERN = Pattern.compile("^[a-f\\d]{32,256}$");

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 不为null才进行校验
        if (value != null) {
            Matcher matcher = PATTERN.matcher(value);
            return matcher.find();
        }
        return true;
    }
}

编程式校验

上面的示例都是基于注解来实现自动校验的,在某些情况下,我们可能希望以编程方式调用验证。这个时候可以注入
javax.validation.Validator 对象,然后再调用其 api。

@Autowired
private javax.validation.Validator globalValidator;

// 编程式校验
@PostMapping("/saveWithCodingValidate")
public Result saveWithCodingValidate(@RequestBody UserDTO userDTO) {
Set<constraintviolation> validate = globalValidator.validate(userDTO, UserDTO.Save.class);
    // 如果校验通过,validate 为空;否则,validate 包含未校验通过项
    if (validate.isEmpty()) {
    // 校验通过,才会执行业务逻辑处理

    } else {
        for (ConstraintViolation userDTOConstraintViolation : validate) {
            // 校验失败,做其它逻辑
            System.out.println(userDTOConstraintViolation);
        }
    }
    return Result.ok();

}

快速失败(Fail Fast)配置

Spring Validation 默认会校验完所有字段,然后才抛出异常。可以通过一些简单的配置,开启 Fali Fast 模式,一旦校验失败就立即返回。

@Bean
public Validator validator() {
    ValidatorFactory validatorFactory = Validation.byProvider(Hibernateva lidator.class)
          .configure()
          // 快速失败模式
          .failFast(true)
          .buildValidatorFactory();
    return validatorFactory.getValidator();
}

校验信息的国际化

Spring 的校验功能可以返回很友好的校验信息提示,而且这个信息支持国际化。

这块功能暂时暂时不常用,具体可以参考这篇文章

@Validated 和@Valid 的区别联系

首先,@Validated 和@Valid 都能实现基本的验证功能,也就是如果你是想验证一个参数是否为空,长度是否满足要求这些简单功能,使用哪个注解都可以。

但是这两个注解在分组、注解作用的地方、嵌套验证等功能上两个有所不同。下面列下这两个注解主要的不同点。

  • @Valid 注解是 JSR303 规范的注解,@Validated 注解是 Spring 框架自带的注解;
  • @Valid 不具有分组校验功能,@Validate 具有分组校验功能;
  • @Valid 可以用在方法、构造函数、方法参数和成员属性(字段)上,@Validated 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能;
  • @Valid 加在成员属性上可以对成员属性进行嵌套验证,而@Validate 不能加在成员属性上,所以不具备这个功能。

这边说明下,什么叫嵌套验证。

我们现在有个实体叫做 Item:

public class Item {

    @NotNull(message = "id不能为空")
    @Min(value = 1, message = "id必须为正整数")
    private Long id;

    @NotNull(message = "props不能为空")
    @Size(min = 1, message = "至少要有一个属性")
    private List<Prop> props;

}

Item 带有很多属性,属性里面有:pid、vid、pidName 和 vidName,如下所示:

public class Prop {

    @NotNull(message = "pid不能为空")
    @Min(value = 1, message = "pid必须为正整数")
    private Long pid;

    @NotNull(message = "vid不能为空")
    @Min(value = 1, message = "vid必须为正整数")
    private Long vid;

    @NotBlank(message = "pidName不能为空")
    private String pidName;

    @NotBlank(message = "vidName不能为空")
    private String vidName;

}

属性这个实体也有自己的验证机制,比如 pid 和 vid 不能为空,pidName 和 vidName 不能为空等。
现在我们有个 ItemController 接受一个 Item 的入参,想要对 Item 进行验证,如下所示:

@RestController
public class ItemController {

    @RequestMapping("/item/add")
    public void addItem(@Validated Item item, BindingResult bindingResult) {
        doSomething();
    }

}

在上图中,如果 Item 实体的 props 属性不额外加注释,只有@NotNull 和@Size,无论入参采用@Validated 还是@Valid 验证,Spring Validation 框架只会对 Item 的 id 和 props 做非空和数量验证,不会对 props 字段里的 Prop 实体进行字段验证,也就是@Validated 和@Valid 加在方法参数前,都不会自动对参数进行嵌套验证。也就是说如果传的 List 中有 Prop 的 pid 为空

首页 上一页 2 3 4 5 6 7 下一页 尾页 5/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇记录一次解决数据库连接池连接泄.. 下一篇Tomcat+Eclipse乱码问题解决方法

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目