依赖:spring‑boot‑starter‑validation 分两组:javax(Boot2) / jakarta(Boot3),注解名字完全一样,只是包名变了。 使用:写在 DTO 的字段上,配合 @Valid / @Validated 生效。
一、空值相关
| 注解 | 说明 |
@NotNull |
不能为 null;空字符串""、空格可以通过 |
@Null |
必须是 null |
@NotBlank |
字符串专用:不能null,不能空串,不能全空格 |
@NotEmpty |
集合/数组/字符串:不能null,长度不能为0;允许全空格 |
public class UserDTO {
@NotNull(message = "用户id不能为null")
private Long userId;
@NotBlank(message = "用户名不能为空,不能全空格")
private String username;
@NotEmpty(message = "角色列表不能为空")
private List<String> roleList;
}
区分重点:
@NotNull:对象不为null,字符串传""能过
@NotBlank:只用于String,拒绝null、""、" "
@NotEmpty:字符串/集合,拒绝null、空集合,但是 " " 空格字符串可以过
二、数字校验(int、Integer、BigDecimal等)
| 注解 | 说明 |
@Min(value = 10) |
数字 ≥ 10 |
@Max(value = 100) |
数字 ≤100 |
@Positive |
正数 >0 |
@PositiveOrZero |
≥0 |
@Negative |
负数 <0 |
@NegativeOrZero |
≤0 |
@Digits(integer=3, fraction=2) |
数字最多3位整数,2位小数 |
public class UserDTO {
@Min(value = 18, message = "年龄最小18岁")
private Integer age;
@Positive(message = "金额必须大于0")
private BigDecimal amount;
@Digits(integer = 5, fraction = 2, message = "金额最多5位整数,2位小数")
private BigDecimal money;
}
三、字符串长度、正则
| 注解 | 说明 |
@Size(min=2,max=20) |
集合/字符串:长度范围 |
@Pattern(regexp="正则") |
正则表达式匹配 |
public class UserDTO {
@Size(min = 2, max = 10, message = "昵称2‑10个字符")
private String nickName;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误")
private String phone;
}
注意:@Size 判断字符串字符个数;不要用来判断数字大小。
四、日期、时间
| 注解 | 说明 |
@Past |
必须是过去的时间 |
@PastOrPresent |
过去或者现在 |
@Future |
必须是未来时间 |
@FutureOrPresent |
未来或者现在 |
public class UserDTO {
@Past(message = "生日必须是过去日期")
private LocalDate birthday;
}
五、布尔
| 注解 | 说明 |
@AssertTrue |
必须为true |
@AssertFalse |
必须为false |
public class UserDTO {
@AssertTrue(message = "必须同意协议")
private Boolean agree;
}
DTO完整示例
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
public class UserDTO {
@NotNull(message = "用户ID不能为空")
private Long userId;
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 16, message = "用户名2‑16字符")
private String username;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@Min(value = 18, message = "年龄必须大于等于18")
private Integer age;
@Positive(message = "账户金额必须大于0")
private BigDecimal balance;
@NotEmpty(message = "角色不能为空")
private List<String> roles;
@Past(message = "生日必须是过去日期")
private LocalDate birthday;
@AssertTrue(message = "请同意用户协议")
private Boolean agreeProtocol;
// getter setter 省略
}
Controller调用示例
@RestController
@Validated
public class UserController {
@PostMapping("/user/save")
public String save(@Valid @RequestBody UserDTO dto) {
return "ok";
}
}
补充两个容易踩坑点
@Valid 写在参数前面,不能写在字段上;类上写@Validated
- 如果是普通URL参数(不是@RequestBody),必须类上加
@Validated,字段注解才生效
@GetMapping("/query")
public void query(@NotNull(message="id不能为空") Long id){}
- 嵌套对象校验:DTO里面包含另一个对象,需要加
@Valid
public class UserDTO{
@Valid // 嵌套对象,必须加@Valid才会校验子对象字段
private AddressDTO address;
}