实体类校验需语义精准:@NotBlank用于非空字符串,@NotNull用于包装类型必传,@NotEmpty用于集合非空;格式校验用@Email/@Pattern;范围校验须带message说明业务原因;嵌套对象加@Valid启用级联;分组校验按Create/Update场景差异化约束。

在实体类中写清楚校验规则,核心是让每个字段的约束意图一目了然,既方便协作阅读,也利于后期维护和调试。不需要堆砌注解,而要讲逻辑、分场景、有层次。
字段级校验注解要精准匹配语义
不同“空”的含义不能混用:
- @NotBlank:专用于字符串,表示非 null 且 trim 后长度 > 0(比如用户名、昵称)
- @NotNull:适用于包装类型(Integer、LocalDateTime 等),强调“必须传值”,不关心内容(比如订单状态码、创建时间)
- @NotEmpty:用于 List、Set、Map,表示非 null 且 size > 0(比如商品 SKU 列表、收货地址集合)
- 邮箱、手机号、URL 等格式校验,优先用 @Email、@Pattern(配明确正则),避免手写 if 判断
长度与数值范围需带业务提示
仅写 @Size(min=2, max=20) 不够,要说明“为什么是这个范围”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 加 message 属性,用自然语言表达业务规则,例如:
@Size(min = 2, max = 16, message = "姓名长度需为2–16个汉字或字母") - 数值类用 @Min/@Max 时,注明单位或上下文,例如:
@Min(value = 0, message = "折扣率不能为负数")
@Max(value = 100, message = "折扣率最高为100%,即全额减免")
嵌套对象必须显式开启级联校验
如果实体里包含另一个对象(如 User 包含 Profile),只在 Profile 类里加校验注解是不够的:
- 在 User 的 profile 字段上加 @Valid,这是触发递归校验的开关
- Profile 内部字段(如 nickname、age)仍需各自配 @NotBlank、@Min 等注解
- 不要漏掉 Controller 层参数的 @Validated 或 @Valid,否则整个链路不会启动
分组校验让规则按场景生效
同一字段在不同接口中可能有不同要求(如新增时 nickname 必填,编辑时可选):
- 定义空接口作分组标记,例如:
public interface Create {}
public interface Update {} - 字段注解指定 groups:
@NotBlank(groups = Create.class)
@Size(max = 20, groups = {Create.class, Update.class}) - Controller 方法用 @Validated(Create.class) 指定当前启用哪组规则

















