惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
罗磊的独立博客
IT之家
IT之家
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
博客园 - Franky
博客园 - 聂微东
博客园_首页
爱范儿
爱范儿
量子位
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
Martin Fowler
Martin Fowler
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
Vercel News
Vercel News
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
Engineering at Meta
Engineering at Meta

博客园 - 轻舟软件

函数式接口简介 轻舟分公司协作平台:统一管理、高效协作 [ERR] 1118 - Row size too large (> 8126) IDEA中Java代码修改后及时生效的方法 python SQLite 访问组件 AI课堂笔记:AI编程 轻舟项目管理系统:台账・文件・协作・管控,让项目告别混乱,有序可控! 分公司项目的柔性管理(造价咨询、招标代理) 咨询行业——项目费用管控 咨询行业——项目管理模型 Java8:函数式接口、Lambda、Stream Java知识图谱(转) 简约至上 软件需求分析方法论(转) EasyUI的属性、事件、方法的使用 两位小数偶感 什么是函数? HQL分页查询、分组查询 MySql 、Oracle 获取表结构和字段信息 马云卸任演讲全文(2019-09-10) MySQL权限管理常用命令
JSR303 常用校验注解(validation)
轻舟软件 · 2026-08-24 · via 博客园 - 轻舟软件

依赖: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";
    }
}

补充两个容易踩坑点

  1. @Valid 写在参数前面,不能写在字段上;类上写@Validated
  2. 如果是普通URL参数(不是@RequestBody),必须类上加@Validated,字段注解才生效
@GetMapping("/query")
public void query(@NotNull(message="id不能为空") Long id){}
  1. 嵌套对象校验:DTO里面包含另一个对象,需要加 @Valid
public class UserDTO{
    @Valid // 嵌套对象,必须加@Valid才会校验子对象字段
    private AddressDTO address;
}