JSR303快速入门

1.什么是JSR

  JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

2.什么是JSR303

  JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

3.快速使用

3.1 给bean添加校验注解

该注解被定义在 javax.validation.constraints 包下面

    @NotNull
    private String name;

自定义校验规则

    @Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是一个字母")
    private String productUnit;

3.2 开启校验

在需要校验的接口添加注解@Valid,例如:

3.3 调用接口

调用接口的时候我们可以看到校验规则已生效,校验错误以后就会有默认的响应

3.4 自定义返回结果

上述校验失败后的返回结果不满足我们统一返回给前端的样式,所以我们现在需要给校验失败重新返回信息,给校验的bean后紧一个 BindingResult ,就可以获取到校验的结果

完整写法如下:

    @RequestMapping("/update")
    public R update(@Valid @RequestBody CategoryEntity category, BindingResult result) {
        if (result.hasErrors()) {
            Map<String, String> map = new HashMap<>();
            //获取校验的错误结果
            List<FieldError> fieldErrors = result.getFieldErrors();
            fieldErrors.forEach(fieldError -> {
                String message = fieldError.getDefaultMessage();//错误提示消息
                String field = fieldError.getField(); //获取错误的属性名
                map.put(field, message);
            });
            return R.error(400, "提交的数据不合法").put("map", map);
        }
        categoryService.updateById(category);
        return R.ok();
    }

再次响应结果如下:

4.分组校验

4.1 使用场景

 同一个字段有在不同的场景应该有不同的校验规则,比如id在添加的时候必须为空,而在修改的时候不能为空

这时我们可以对id进行分租校验,如下:

    @NotNull(message = "修改不能为空",groups = UpdateGroup.class)
    @Null(message = "新增必须为空",groups = AddGroup.class)
    @TableId
    private Long catId;

4.2 开启校验

给校验注解标注什么情况下进行校验

    @RequestMapping("/update")
    public R update(@Validated({UpdateGroup.class}) @RequestBody CategoryEntity category) {
        categoryService.updateById(category);
        return R.ok();
    }

注:默认没有指定分组的校验注解在分组校验情况下不生效。

5.自定义校验

5.1 编写自定义校验注解

Constraint中指定校验规则类

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {ListValueConstraintValidator.class}
)
public @interface ListValue {

    String message() default "{com.gh.common.valid.ListValue.message}";

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

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

    int[] vals() default { };
}

5.2 编写自定义校验规则器

创建校验规则类,实现ConstraintValidator接口,其中两个参数的含义分别是:第一个代表自定义的注解,第二个代表被校验属性的类型

public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {

    private Set<Integer> set = new HashSet<>();

    //初始化,接收到注解里的值
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] vals = constraintAnnotation.vals();
        if (vals != null && vals.length > 0) {
            for (int val : vals) {
                set.add(val);
            }
        }
    }

    //判断是否校验成功
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
        return set.contains(value);
    }
}

5.3 自定义校验失败消息

在resources目录下新建一个文件ValidationMessages.properties,在里面指定校验失败的消息

com.gh.common.valid.ListValue.message=必须提交指定的值

而此消息在自定义注解的message的default中指定

5.4 使用自定义注解

这里指定传入的值必须为1或0,否则会校验失败

    @ListValue(vals = {0, 1}, groups = UpdateGroup.class)
    @TableLogic(value = "1", delval = "0")
    private Integer showStatus;

5.5 校验结果

当我们传入的值为3时会触发

一点点学习,一丝丝进步。不懈怠,才不会被时代所淘汰!

原文地址:https://www.cnblogs.com/fqh2020/p/15585341.html