SpringBoot使用Bean Validation实现参数校验
更新时间:2026年07月15日 09:30:58 作者:张老师技术栈
还在为接口参数校验头疼吗,本文带你快速掌握Bean Validation(JSR303)的常用校验注解,比如@NotNull、@NotBlank、@Email等,还教你如何实现分组校验和自定义校验注解,让校验逻辑和业务代码彻底分离,轻松处理校验异常,需要的朋友可以参考下
参数校验是后端接口的第一道防线。如果让前端传过来的脏数据直接进入业务逻辑,后面排查起来非常麻烦。Bean Validation(JSR 303)提供了一套声明式校验注解,让校验逻辑和业务逻辑分离。
一、为什么需要参数校验
// ❌ 不校验参数,直接用
@PostMapping("/user")
public ResultVO<User> createUser(@RequestBody User user) {
// 如果 user.name 为空,保存到数据库后会报错
// 如果 user.age = -1,业务逻辑会出问题
// 如果 user.email 格式不对,其他地方会解析失败
return ResultVO.success(userService.save(user));
}
// ✅ 使用注解校验
@PostMapping("/user")
public ResultVO<User> createUser(@RequestBody @Valid User user) {
return ResultVO.success(userService.save(user));
}
二、常用校验注解
@Data
public class UserCreateDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在{min}-{max}之间")
private String username;
@NotBlank(message = "密码不能为空")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d).{6,20}$",
message = "密码必须包含字母和数字,长度6-20")
private String password;
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@Email(message = "邮箱格式不正确")
private String email;
@NotNull(message = "年龄不能为空")
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
@NotNull(message = "性别不能为空")
@Range(min = 0, max = 2, message = "性别值不正确")
private Integer gender;
@DecimalMin(value = "0.01", message = "金额不能小于0.01")
@DecimalMax(value = "999999.99", message = "金额超限")
private BigDecimal amount;
@Future(message = "过期时间必须是将来的时间")
private LocalDateTime expireTime;
@Size(min = 1, max = 10, message = "角色数量1-10个")
private List<@NotBlank String> roles;
}
三、分组校验
// 定义分组接口
public interface CreateGroup {}
public interface UpdateGroup {}
@Data
public class UserDTO {
@Null(groups = CreateGroup.class, message = "新增时ID必须为空")
@NotNull(groups = UpdateGroup.class, message = "修改时ID不能为空")
private Long id;
@NotBlank(groups = CreateGroup.class, message = "用户名不能为空")
private String username;
@NotBlank(groups = CreateGroup.class, message = "密码不能为空")
private String password;
private String email;
}
@PostMapping
public ResultVO<?> create(@RequestBody @Validated(CreateGroup.class) UserDTO dto) {
return ResultVO.success(userService.create(dto));
}
@PutMapping("/{id}")
public ResultVO<?> update(@PathVariable Long id,
@RequestBody @Validated(UpdateGroup.class) UserDTO dto) {
dto.setId(id);
return ResultVO.success(userService.update(dto));
}
四、自定义校验注解
1. 创建注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {
String message() default "手机号格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2. 实现校验器
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private static final Pattern PHONE_PATTERN =
Pattern.compile("^1[3-9]\\d{9}$");
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return true; // 空值由 @NotBlank 处理
}
return PHONE_PATTERN.matcher(value).matches();
}
}
3. 使用
@Data
public class UserDTO {
@Phone(message = "手机号格式错误")
private String phone;
}
五、校验异常处理
@RestControllerAdvice
public class ValidationExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO<?> handleValidation(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldErrors().stream()
.map(err -> err.getField() + ": " + err.getDefaultMessage())
.collect(Collectors.joining("; "));
return ResultVO.error(400, msg);
}
@ExceptionHandler(ConstraintViolationException.class)
public ResultVO<?> handleConstraint(ConstraintViolationException e) {
String msg = e.getConstraintViolations().stream()
.map(v -> v.getPropertyPath() + ": " + v.getMessage())
.collect(Collectors.joining("; "));
return ResultVO.error(400, msg);
}
}
六、常用注解速查
| 注解 | 作用 | 支持类型 |
|---|---|---|
| @NotNull | 值不能为 null | 所有类型 |
| @NotBlank | 字符串不能为 null 且不能全空格 | String |
| @NotEmpty | 集合/字符串不能为空 | String/Collection/Map/数组 |
| @Size | 长度/大小在指定范围内 | String/Collection/Map/数组 |
| @Min/@Max | 数值最小值/最大值 | 数值类型 |
| @Range | 数值在指定范围内 | 数值类型 |
| 邮箱格式 | String | |
| @Pattern | 正则表达式匹配 | String |
| @Past/@Future | 过去/将来的时间 | Date/LocalDate |
| @DecimalMin/@DecimalMax | 精确数值范围 | BigDecimal |
以上就是SpringBoot使用Bean Validation实现参数校验的详细内容,更多关于SpringBoot Bean Validation参数校验的资料请关注脚本之家其它相关文章!
相关文章
cookie+mybatis+servlet实现免登录时长两天半的整体流程
这篇文章主要介绍了cookie+mybatis+servlet实现免登录时长两天半,主要用到的技术有session、cookie、转发、重定向、filter、和servlet,最重要的还是具体的来运用它们在前端页面真正的搭建出一个应用,通过这个练习,对我们所学的web知识做一个整合,需要的朋友可以参考下2022-10-10
idea在用Mybatis时xml文件sql不提示解决办法(提示后背景颜色去除)
mybatis的xml文件配置的时候,有时候会没有提示,这让我们很头疼,下面这篇文章主要给大家介绍了关于idea在用Mybatis时xml文件sql不提示的解决办法,提示后背景颜色去除的相关资料,需要的朋友可以参考下2023-03-03


最新评论