默认分类 32 0

    JSR303 分组校验

    简介

    JSR 303 是 Java 规范请求(Java Specification Request)的一部分,全称为 “JSR 303: Bean Validation”,它定义了一套标准的 Java Bean 校验 机制,主要用于 输入数据校验。JSR 303 通常与 Spring BootJakarta EE 结合使用,通过注解的方式对 Java Bean 进行约束,确保数据符合预期要求,从而提高数据的可靠性和安全性。

    常见注解

    注解 说明
    @Null 限制字段的值必须为 null
    @NotNull 限制字段的值 不能为空(即不能为 null)。
    @AssertFalse 限制字段的值必须为 false
    @AssertTrue 限制字段的值必须为 true
    @DecimalMax(value) 限制字段的值不能大于指定的 value
    @DecimalMin(value) 限制字段的值不能小于指定的 value
    @Digits(integer, fraction) 限制字段为一个小数,整数部分最多 integer 位,小数部分最多 fraction 位。
    @Future 限制字段的值必须是将来的日期。
    @Past 限制字段的值必须是过去的日期。
    @Max(value) 限制字段的值不能大于指定的 value(适用于整数)。
    @Min(value) 限制字段的值不能小于指定的 value(适用于整数)。
    @Pattern(regexp) 限制字段的值必须符合指定的 正则表达式
    @Size(min, max) 限制字段的长度必须在 minmax 之间(适用于 StringCollectionMapArray)。
    @NotEmpty 限制字段的值不能为空(适用于 StringCollectionMap,长度必须 > 0)。
    @NotBlank 限制字段的值不能为空且去除前后空格后长度必须 > 0,与 @NotEmpty 的区别在于 @NotBlank 仅适用于 String
    @Email 限制字段的值必须是一个合法的 Email 地址,可以使用正则表达式和 flag 参数指定自定义格式。

    说明

    • @Null@NotNull 是互斥的,一个字段不能同时使用它们。
    • @Future@Past 主要用于 Date 类型,用于验证时间有效性。
    • @NotEmpty@NotBlank 适用于不同类型的字段:
      • @NotEmpty 可用于 集合、数组、字符串,必须有元素。
      • @NotBlank 仅适用于 字符串,且会 忽略空格
    • @Pattern(regexp = "正则表达式") 可用于限制字符串格式,例如:

    要校验的DTO

    @Data
    @ApiModel(value = "AddCourseDto", description = "新增课程基本信息")
    public class AddCourseDto {  
      
        @NotEmpty(message = "新增课程名称不能为空", groups = {ValidationGroups.Insert.class})  
        @NotEmpty(message = "修改课程名称不能为空", groups = {ValidationGroups.Update.class})  
        @ApiModelProperty(value = "课程名称", required = true)  
        private String name;  
      
        @NotEmpty(message = "适用人群不能为空")  
        @Size(message = "适用人群内容过少", min = 10,groups = {ValidationGroups.Insert.class})  
        @ApiModelProperty(value = "适用人群", required = true)  
        private String users;  
      
        @ApiModelProperty(value = "课程标签")  
        private String tags;  
      
        @NotEmpty(message = "课程分类不能为空")  
        @ApiModelProperty(value = "大分类", required = true)  
        private String mt;
    }
    

    如果校验出错Spring会抛出MethodArgumentNotValidException异常,我们需要在统一异常处理器中捕获异常,解析出异常信息。

    @ResponseBody  
    @ExceptionHandler(MethodArgumentNotValidException.class)  
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)  
    public RestErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {  
        BindingResult bindingResult = e.getBindingResult();  
        List<String> msgList = new ArrayList<>();  
        //将错误信息放在msgList  
        bindingResult.getFieldErrors().stream().forEach(item -> msgList.add(item.getDefaultMessage()));  
        //拼接错误信息  
        String msg = StringUtils.join(msgList, ",");  
        log.error("【系统异常】{}", msg);  
        return new RestErrorResponse(msg);  
    }
    

    分组校验

    有时,一个属性上的校验规则是不同的,例如订单的编号由系统生成,所以在创建订单时要求订单编号为空,在更新时要求订单编号不为空,此时就用到了分组校验,同一个属性定义多个校验规则属于不同的分组,比如:添加订单定义@NULL规则属于insert分组,更新订单定义@NotEmpty规则属于update分组,insert和update是分组的名称,是可以修改的。

    代码如下:

    可以用class类型来表示不同的分组

    public class ValidationGroups {  
      
     public interface Insert{};  
     public interface Update{};  
     public interface Delete{};  
      
    }
    

    其中,groups是一个数组,代表该校验的组

    @NotEmpty(message = "新增课程名称不能为空", groups = {ValidationGroups.Insert.class})  //新增时校验这个
    @NotEmpty(message = "修改课程名称不能为空", groups = {ValidationGroups.Update.class})  //修改时校验这个
    @ApiModelProperty(value = "课程名称", required = true)  
    private String name;
    

    在controller使用@Validated指定组,可以多个

    @ApiOperation("新增课程基础信息")  
    @PostMapping("/course")  
    public CourseBaseInfoDto createCourseBase(@RequestBody @Validated({ValidationGroups.Insert.class}) AddCourseDto addCourseDto) {  
        Long companyId = 1232141425L;  
        return courseBaseInfoService.createCourseBase(companyId, addCourseDto);  
    }
    

    注意

    没有使用groups的其他校验字段,在conterller指定采用分组校验模式,其他字段不生效(不校验)

    Warning: Undefined array key "HTTP_ACCEPT_LANGUAGE" in /usr/home/LXX123/domains/www.lxxblog.cfd/public_html/usr/themes/Farallon/comments.php on line 4 Deprecated: stripos(): Passing null to parameter #1 ($haystack) of type string is deprecated in /usr/home/LXX123/domains/www.lxxblog.cfd/public_html/usr/themes/Farallon/comments.php on line 4