Spring参数校验注解 - @Valid / @Validated
目录
前言
"对于任何一个项目来说,对接口的参数进行校验是必不可少的,最简单的方法就是在代码中直接检查参数。然而,这种方法显然不够优雅。Spring 提供了一种更优雅的方法来实现参数校验,本文将对此进行详细说明。"
一、@Valid / @Validated的区别
-
@Validated // 支持类上,方法,方法参数上注解,支持指定group分组,不支持嵌套对象自动校验
-
@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 分组的校验规则。