Spring Boot Validation 使用手册

13 阅读1分钟

Spring Boot Validation 使用手册

目标:5 分钟上手,覆盖 99% 场景,避坑指南 + 速查表


一、@Valid vs @Validated —— 关键区别

特性@Valid (JSR-303)@Validated (Spring 扩展)
来源Java 标准(javax.validation)Spring 框架提供
分组校验✅ 支持✅ 支持(更常用)
方法级校验❌ 不支持✅ 支持(但需在类或方法上显式标注)
参数校验❌ 仅支持 @RequestBody✅ 支持 @RequestParam / @PathVariable

✅推荐用法:

  • Controller 层:

    • 简单校验 → @Valid

    • 需分组 或 校验 查询/路径参数 → @Validated

  • Service 层 → 仅在需要校验的类/方法上加 @Validated


二、快速启用

1. 引入依赖(Spring Boot 2.3+ 需手动加)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. Service 层校验

// 方式1:在 Service 类上加 @Validated(推荐)
@Service
@Validated // ← 仅此 Service 启用方法校验
public class UserService {
    public void save(@Valid UserCreateDTO dto) { // 自动校验
        // ...
    }
}

// 方式2:在具体方法上加(不常用)
@Service
public class OrderService {
    @Validated
    public void createOrder(@Valid OrderDTO dto) {
        // ...
    }
}

三、所有常用注解速查表

基础校验

注解说明示例
@NotNull不能为 null@NotNull Long id
@NotEmpty非 null 且非空(Collection/String)@NotEmpty List<String> tags
@NotBlank字符串专用:trim 后非空@NotBlank String username

💡 字符串必填优先用 @NotBlank(防 " " 空格)

数值 & 日期

注解说明示例
@Min(0) / @Max(100)整数范围@Min(18) Integer age
@DecimalMin("0.01")小数范围BigDecimal price
@Positive> 0@Positive Integer count
@Past / @Future日期校验@Past LocalDate birthday

格式校验

注解说明示例
@Size(min=6, max=20)长度@Size(min=6) String password
@Email邮箱@Email String email
@Pattern(regexp = "...")正则@Pattern(regexp = "^1[3-9]\d{9}$") String phone
@URLURL 格式@URL String homepage

四、高级用法

1. 嵌套对象校验

public class OrderDTO {
    @Valid // ← 关键!否则 Address 不校验
    private Address shippingAddress;
}

2. List 元素校验(⚠️ 注意兼容性)

// JDK ≥ 8u20 + Spring Boot ≥ 2.3 才支持
private List<@Valid OrderItem> items;

// 兼容写法(推荐)
public class ItemList {
    @Valid
    private List<OrderItem> items;
}

3. 分组校验

public interface Create {}
public interface Update {}

public class UserDTO {
    @Null(groups = Create.class)
    @NotNull(groups = Update.class)
    private Long id;
}

// Controller
public Result create(@Validated(Create.class) @RequestBody UserDTO dto) { ... }

五、避坑指南(必看!)

问题原因解决方案
校验不生效忘记加 @Valid/@ValidatedController 参数前加注解
嵌套对象不校验字段没加 @Valid在嵌套字段上加 @Valid
Service 层无效Service 类未加 @Validated只在需要的 Service 上加 @Validated
List 校验失效JDK/Spring Boot 版本低用封装类或手动校验
参数校验失败用 @Valid 校验 @RequestParam改用 @Validated

六、最佳实践

  1. DTO 专用:只在校验 DTO,不在 Entity 上校验

  2. 错误消息友好:message = "密码长度需6-20位"

  3. 复杂逻辑放 Service:如“用户名不能重复” → Service 中查 DB

  4. Service 校验按需开启:仅在需要参数校验的 Service 上加 @Validated

  5. 快速测试:看是否返回自定义错误(不是 500)

✅ 记住:Validation 只做“格式”校验,不做“业务”校验!

七、速查 Cheat Sheet

场景用法示例
字符串非空@NotBlank@NotBlank String name
数字范围@Min + @Max@Min(1) @Max(100) Integer score
邮箱@Email@Email String email
手机号@Pattern@Pattern(regexp = "^1[3-9]\d{9}$")
分组校验@Validated(Group.class)Controller 参数
Service 校验在 Service 类上加 @Validated@Service @Validated public class XxxService
查询参数校验必须 @Validated@RequestParam @Min(1) int page