Spring参数校验注解 - @Valid / @Validated

目录

前言

二、使用步骤

引入库

1.URL校验

2.表单校验

3.嵌套校验

4.分组校验


前言

        "对于任何一个项目来说,对接口的参数进行校验是必不可少的,最简单的方法就是在代码中直接检查参数。然而,这种方法显然不够优雅。Spring 提供了一种更优雅的方法来实现参数校验,本文将对此进行详细说明。"


一、@Valid / @Validated的区别

  1. @Validated // 支持类上,方法,方法参数上注解,支持指定group分组,不支持嵌套对象自动校验

  2. @Valid // 不支持类上注解,不支持指定group分组,但是支持嵌套对象的字段自动校验

二、使用步骤

引入库

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.5.5</version>
</dependency>

1.URL校验

@RestController
@Validated
public class MyController {
}
@GetMapping("/test")
public R test(@NotBlank @RequestParam String p1, @Range(max = 50, min = 10) @RequestParam int p2) {
    //业务逻辑 
    return R.ok();
}

注意需要在类上加一个@Validated注解,否则可能无法校验成功。

2.表单校验

@Data
@AllArgsConstructor
public class User {

    private String id;

    @NotBlank
    @Size(max = 20)
    private String name;

    @NotNull
    @Pattern(regexp = "[A-Z][a-z][0-9]")
    private String password;
    
    @NotNull
    private Integer age;

    @Max(10)
    @Min(1)
    private Integer level;
}
   @PostMapping("/user")
    public R handle(@Validated @RequestBody User user, BindingResult result) {
        if (result.hasErrors()) {
            result.getAllErrors().forEach(s -> System.out.println(s.getDefaultMessage()));
             return R.fail(result.getAllErrors().get(0).getDefaultMessage());
        }
        return R.success();
    }

 上述例子中,我们可以通过BindingResult参数拿到错误信息并处理。

3.嵌套校验

@Data
public class ClassDto {
    /**
     * 班级名称
     */
    @NotBlank(message = "班级名称不能为空!")
    private String name;
    /**
     * 班级人员
     */
    @NotNull(message = "学生不能为空!")
    @Valid
    private List<StudentDto> studentList;
}

4.分组校验

public interface CreateGroup { }
public interface UpdateGroup { }
@Data
public class User {

    @NotBlank(groups = CreateGroup.class)
    private String userName;

    @NotBlank(groups = {CreateGroup.class, UpdateGroup.class})
    private String password;
}


在控制器类中,可以使用 @Validated 注解的 groups 属性来指定使用哪个分组的校验规则:

@RestController
public class UserController {
@PostMapping("/users")
public void createUser(@RequestBody @Validated(CreateGroup.class) User user) {

}

@PutMapping("/users/{id}")
public void updateUser(@PathVariable Long id, @RequestBody @Validated(UpdateGroup.class) User user) {

}

在这种情况下,createUser 方法只会使用 CreateGroup 分组的校验规则,而 updateUser 方法则会使用 UpdateGroup 分组的校验规则。