核心作用
Controller 层的请求参数校验(@RequestParam、@PathVariable、POJO 对象等)
Service 层的方法入参校验
配置类(@ConfigurationProperties)的属性校验
1. 在 Controller 类上添加 @Validated
javascript
@RestController
@Validated // 👈 启用方法参数校验
public class UserController {
// 校验单个参数
@GetMapping("/user")
public String getUser(
@RequestParam @NotBlank String name,
@RequestParam @Min(1) Integer age
) {
return "Hello " + name + ", age: " + age;
}
// 校验 POJO 对象
@PostMapping("/user")
public User createUser(@Valid @RequestBody CreateUserRequest request) {
return userService.save(request);
}
}
2. 常用校验注解(需配合 @Validated)
| 注解 | 说明 | 示例 |
|---|---|---|
@NotNull |
不能为 null | @NotNull String email |
@NotBlank |
字符串非 null 且非空(trim 后长度 > 0) | @NotBlank String username |
@NotEmpty |
集合/数组/字符串非 null 且 size > 0 | @NotEmpty List<String> tags |
@Min(1) / @Max(100) |
数值范围 | @Min(0) Integer count |
@Email |
邮箱格式 | @Email String email |
@Pattern(regexp = "...") |
正则匹配 | @Pattern(regexp = "^1[3-9]\\d{9}$") String phone |
放在形参上
- @Validated 在作用于 @RequestBody 对象时,是作为 @Valid 的增强版存在的。
- 它不是用于激活 @RequestParam 这类简单参数的校验(那种情况必须类上加 @Validated),而是用于控制对象校验的行为(尤其是分组)。
| 用法 | 是否有效 | 用途 |
|---|---|---|
@Validated 放在 Controller 类上 |
✅ | 激活 @RequestParam / @PathVariable 等简单参数的校验 |
@Validated 放在 @RequestBody 参数上 |
✅ | 对 POJO 对象进行校验,支持分组(即使没写分组也合法) |
@Validated 放在 @RequestParam String name 上 |
❌ | 无效! 简单参数校验必须依赖类上的 @Validated |
javascript
public AjaxResult add(@Validated @RequestBody SysDictData dict)
javascript
public class SysDictData {
@NotBlank(message = "字典标签不能为空")
private String dictLabel;
@NotNull(message = "字典排序不能为空")
private Integer dictSort;
// ...
}
这里注意的是如果不用分组的功能 , @Validated @Valid 作用就是一致的
分组
| 场景 | 字段要求 |
|---|---|
| 新增用户 | id 可为空,username、email 必填 |
| 修改用户 | id 必须存在,username、email 可选 |
| 重置密码 | 只需 id 和 newPassword,其他字段忽略 |
步骤 1:定义分组接口(空接口即可)
javascript
public interface AddGroup {} // 新增分组
public interface UpdateGroup {} // 修改分组
public interface PasswordGroup {} // 密码相关分组
步骤 2:在实体类字段上指定所属分组
javascript
import javax.validation.constraints.*;
public class User {
@NotNull(message = "ID不能为空", groups = UpdateGroup.class)
private Long id;
@NotBlank(message = "用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
private String username;
@Email(message = "邮箱格式不正确", groups = AddGroup.class)
private String email;
@NotBlank(message = "新密码不能为空", groups = PasswordGroup.class)
private String newPassword;
// 默认分组(未指定 groups 的字段属于 Default 分组)
@Size(min = 6, max = 20, message = "密码长度6-20位")
private String password;
}
步骤 3:在 Controller 中使用 @Validated(分组.class)
javascript
@RestController
@Validated // 👈 类上仍建议加(虽非必须,但保持一致性)
public class UserController {
// 新增:只校验 AddGroup + Default 分组
@PostMapping("/add")
public Result add(@Validated(AddGroup.class) @RequestBody User user) {
return userService.add(user);
}
// 修改:校验 UpdateGroup + Default 分组
@PutMapping("/update")
public Result update(@Validated(UpdateGroup.class) @RequestBody User user) {
return userService.update(user);
}
// 重置密码:只校验 PasswordGroup + Default
@PostMapping("/reset-password")
public Result resetPassword(@Validated(PasswordGroup.class) @RequestBody User user) {
return userService.resetPassword(user);
}
}
| 特性 | @Valid |
@Validated |
|---|---|---|
| 支持分组 | ❌ 不支持 | ✅ 支持 @Validated(Group.class) |
| 来源 | JSR-303 标准 | Spring 扩展 |
| 作用位置 | 字段、参数、返回值 | 类、方法、参数 |
| 简单参数校验 | ❌ 不能激活 | ✅ 需配合类上注解 |
捕获校验错误
✅ 触发 SysDictData 对象中所有带有 @NotNull、@NotBlank、@Size 等校验注解的字段的验证
✅ 在校验失败时抛出 MethodArgumentNotValidException
✅ 被 Spring 的异常处理器(如 @ControllerAdvice)正常捕获并处理