Spring Boot 参数校验(基于 Hibernate Validator)
1. 简介与依赖
- 作用:对 Controller 接收的参数进行合法性校验,提升接口健壮性。
- 底层实现:Hibernate Validator(Bean Validation 规范的参考实现)。
- 推荐依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
✅ 自动引入
hibernate-validator
+javax.validation-api
,无需手动管理版本。
2. 使用方式
✅ 校验 @RequestBody
(JSON 对象)
- 在参数前加
@Valid
,无需@Validated
。
java
@PostMapping("/user")
public Result createUser(@Valid @RequestBody User user) { ... }
✅ 校验 @RequestParam
/ @PathVariable
等
- 必须 在 Controller 类(或方法)上加
@Validated
。
java
@RestController
@Validated // ← 关键!
public class UserController {
@GetMapping("/user/{id}")
public Result getUser(@Min(1) @PathVariable Long id) { ... }
}
✅ 最佳实践 :Controller 类统一加 @Validated
,覆盖所有校验场景。
3. 常用注解
非空校验
- @NotNull:验证对象不为null,但允许空字符串或空白字符
- @NotEmpty:验证字符串/集合/数组非null且长度/大小>0(不检查空白字符)
- @NotBlank:验证字符串非null且至少包含一个非空白字符
范围校验
- @Size(min=, max=):限制字符串/集合/数组的长度/大小范围
- @Min:验证数字最小值(含边界值)
- @Max:验证数字最大值(含边界值)
格式校验
- @Email:验证字符串是否符合邮箱格式
- @Pattern(regexp = "..."):通过正则表达式自定义校验规则
时间校验
- @Past:验证日期是否在当前时间之前
- @Future:验证日期是否在当前时间之后
4. 全局异常处理器
统一处理校验失败异常,返回结构化错误信息。有了全局异常处理器,前端可以收到规范化的错误信息
java
@RestControllerAdvice
public class GlobalValidationExceptionHandler {
// 处理 @RequestBody 校验失败
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResult<Map<String, String>> handleRequestBody(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors()
.forEach(e -> errors.put(e.getField(), e.getDefaultMessage()));
return ApiResult.error(400, "参数校验失败").data(errors);
}
// 处理 @RequestParam / @PathVariable 校验失败
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResult<Map<String, String>> handleParams(
ConstraintViolationException ex) {
Map<String, String> errors = new HashMap<>();
ex.getConstraintViolations().forEach(v ->
errors.put(v.getPropertyPath().toString(), v.getMessage()));
return ApiResult.error(400, "参数校验失败").data(errors);
}
}
💡 返回示例:
json
{ "code": 400, "message": "参数校验失败", "data": { "name": "姓名不能为空" } }