Spring Boot Validation 使用手册

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+ 需手动加)

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. Service 层校验

java 复制代码
// 方式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
@URL URL 格式 @URL String homepage

四、高级用法

1. 嵌套对象校验

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

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

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

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

3. 分组校验

java 复制代码
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/@Validated Controller 参数前加注解
嵌套对象不校验 字段没加 @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
相关推荐
柒.梧.1 小时前
吃透Spring Bean:生命周期、单例特性、作用域及扩展方式
java·后端·spring
嘻哈baby2 小时前
接口幂等性设计与实战:支付、下单、重试场景怎么搞?
后端
舒一笑2 小时前
IDEA 调试技巧:关联本地源码,告别反编译代码
后端
UrbanJazzerati2 小时前
PostgreSQL 完全实战指南:从小白到高手 DDL篇
后端·面试
UrbanJazzerati2 小时前
Python实现Salesforce Bulk API 2.0批量数据导入:从Excel到云端的高效方案
后端·面试
豆苗学前端2 小时前
彻底讲透医院移动端手持设备PDA离线同步架构:从"记账本"到"分布式共识",吊打面试官
前端·javascript·后端
用户298698530142 小时前
C#中如何创建目录(TOC):使用Spire.Doc for .NET实现Word TOC自动化
后端·c#·.net
大鹏19882 小时前
警惕 Python 的"甜蜜陷阱":Pickle 反序列化漏洞深度剖析
后端
鱼人2 小时前
PHP 入门指南:从零基础到掌握核心语法
后端