SpringBoot 数据校验(普通校验、分组校验)
MOKE 2020-07-26 AM loading 0条

概述

Spring Validation 验证框架与 javax 都提供了对数据的校验功能,一个是 @Validated(JSR-303变种),一个是 @Valid(标准JSR-303)。


普通校验

添加validation依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- 回顾下lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

通过 LocalValidatorFactoryBean 类可以看到,校验的提示信息可以写在 ValidationMessages.properties 文件中:

    user.name.notnull=用户名不能为空
    user.password.notnull=密码不能为空
    user.email.notnull=邮箱不能为空
    user.email.pattern=邮箱格式不正确

编写User实体类:

        @Data
        public class User {
            @NotNull(message = "{user.name.notnull}")
            private String name;

            @NotNull(message = "{user.password.notnull}")
            private String password;

            @Email(message = "{user.email.pattern}")
            @NotNull(message = "{user.email.notnull}")
            private String email;
        }

这里只是测试,就直接写Controller接口,使用 @Validated 注解:

        @RestController
        @RequestMapping("/valid")
        public class DemoController {

            @PostMapping("/addUser")
            public String addUser(@Validated @RequestBody User user){
                String res = "用户名:"+user.getName()+",密码:"+user.getPassword()+",邮箱:"+user.getEmail();
                return res;
            }
        }

如果校验的结果不对,默认会返回400,这里我们通过ResponseEntityExceptionHandler自定义异常处理类,使得我们的接口能返回错误信息:

        @RestControllerAdvice
        public class ValidatorHandlerAdvice extends ResponseEntityExceptionHandler {
            @Override
            protected ResponseEntity<Object> handleMethodArgumentNotValid(
                    MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status,
                    WebRequest request) {
                List<String> errors = new ArrayList<>();
                List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
                for(ObjectError error : allErrors){
                    errors.add(error.getDefaultMessage());
                }
                return new ResponseEntity(errors, status);
            }
        }

使用 Postman 进行测试:

image-20200725184058279


分组校验

某一个实体中定义了很多的校验规则,但有时候我们并不需要这么多的校验规则,这个时候就可以使用分组校验。

创建两个分组接口:

public interface UserValidationGroup1 {
}
public interface UserValidationGroup2 {
}

修改User实体类:

        @Data
        public class User {
            @NotNull(message = "{user.name.notnull}",groups = {UserValidationGroup1.class, UserValidationGroup2.class})
            private String name;

            @NotNull(message = "{user.password.notnull},groups = {UserValidationGroup1.class, UserValidationGroup2.class}")
            private String password;

            @Email(message = "{user.email.pattern},groups = UserValidationGroup1.class")
            @NotNull(message = "{user.email.notnull},groups = UserValidationGroup2.class")
            private String email;
        }

接口指定分组:

        @RestController
        @RequestMapping("/valid")
        public class DemoController {
            @PostMapping("/addUser")
            public String addUser(@Validated(UserValidationGroup2.class) @RequestBody User user){
                String res = "用户名:"+user.getName()+",密码:"+user.getPassword()+",邮箱:"+user.getEmail();
                return res;
            }
        }

@Validated指定UserValidationGroup2分组,不会校验邮箱格式:

image-20200725190653595


校验注解

注解 作用
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

嵌套校验

有诸如一下形式:

class Person{
    @NotNull
    private String name;
    ...
}
class Room{
    @NotNull
    @Valid  //只能使用@Valid
    List<Person> personList;
}

这样才能对 personList 中的 Person 进行校验。


@Validated和@Valid区别

@Validated 或者@Valid 在基本验证功能上没有太多区别,需要注意的是:

  • 分组:@Validated 有分组功能,而 @Valid 还没有。

  • 作用地方:@Validated 可以用在类型、方法和方法参数,不能用在成员属性上;而 @Valid 可以用在方法、构造函数、方法参数和成员属性上。

标签: Spring

非特殊说明,本博所有文章均为博主原创。

评论啦~


召唤看板娘