Spring Boot中@Valid 与 @Validated 注解的详解
引言
在Spring Boot应用中,参数校验是确保数据完整性和一致性的重要手段。@Valid和@Validated注解是Spring Boot中用于参数校验的两个核心注解。本文将详细介绍这两个注解的用法、区别以及代码样例。
@Valid注解
功能介绍
@Valid是Java EE提供的标准注解,它是JSR 303规范的一部分,主要用于Hibernate Validation等场景。在Spring Boot中,@Valid注解用于触发参数校验,确保请求参数的合法性。
使用场景
@Valid注解可以用于方法参数、构造函数、方法参数和成员属性上。它主要用于嵌套校验,即对于对象中的属性值(可能是另一个对象)进行校验。
代码样例
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.Valid;
public class User {
@NotBlank(message = "用户名不能为空")
private String username;
@NotNull(message = "密码不能为空")
private String password;
@Valid
private Address address;
// Getter 和 Setter
}
public class Address {
@NotBlank(message = "国家不能为空")
private String country;
@NotBlank(message = "城市不能为空")
private String city;
// Getter 和 Setter
}
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@PostMapping("/addUser")
public String addUser(@Valid @RequestBody User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
}
return "用户添加成功";
}
}
在上述代码中,User
类中的address
属性使用了@Valid
注解,表示对address
对象进行嵌套校验。在UserController
中,addUser
方法使用了@Valid
注解对传入的User
对象进行校验,并使用BindingResult
捕获校验错误。
@Validated注解
功能介绍
@Validated是Spring框架特有的注解,属于Spring的一部分,也是JSR 303的一个变种。它提供了一些@Valid所没有的额外功能,比如分组验证。@Validated注解可以用在类、方法和方法参数上,但不能用于成员属性。
使用场景
@Validated注解主要用于支持分组验证,可以更细致地控制验证过程。此外,由于它是Spring专有的,因此可以更好地与Spring的其他功能(如Spring的依赖注入)集成。
代码样例
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.groups.Default;
public interface ValidationGroups {
interface Insert extends Default {}
interface Update {}
}
public class Project {
@NotBlank(message = "ID不能为空", groups = ValidationGroups.Update.class)
private String id;
@NotBlank
private String name;
@Min(value = 1, message = "预算不能小于1", groups = ValidationGroups.Insert.class)
private int budget;
// Getter 和 Setter
}
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.annotation.Validated;
@RestController
public class ProjectController {
@PostMapping("/insertProject")
public String insertProject(@Validated(value = ValidationGroups.Insert.class) @RequestBody Project project, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
}
return "项目插入成功";
}
@PostMapping("/updateProject")
public String updateProject(@Validated(value = ValidationGroups.Update.class) @RequestBody Project project, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
}
return "项目更新成功";
}
}
在上述代码中,我们定义了一个ValidationGroups
接口,用于分组验证。Project
类中的id
属性在Update
分组下必填,而budget
属性在Insert
分组下必填且不能小于1。在ProjectController
中,insertProject
方法使用@Validated(value = ValidationGroups.Insert.class)
注解对传入的Project
对象进行Insert
分组的校验,而updateProject
方法则使用@Validated(value = ValidationGroups.Update.class)
注解进行Update
分组的校验。
@Valid与@Validated的区别
- 嵌套校验:@Valid支持嵌套校验,而@Validated不支持。在需要嵌套校验的场景下,应使用@Valid。
- 分组校验:@Validated支持分组校验,而@Valid不支持。在需要根据不同场景应用不同校验规则的情况下,应使用@Validated。
- 使用范围:@Valid可以用在方法、构造函数、方法参数和成员属性上,而@Validated只能用在类、方法和方法参数上。
结论
@Valid和@Validated注解在Spring Boot的参数校验中扮演着重要角色。掌握这两个注解的用法和区别,可以帮助开发者更灵活地进行参数校验,确保数据的完整性和一致性。