实战演练:如何在Spring Boot项目中优雅地使用参数校验

✅ 空值 / 存在性校验

注解 一句话场景 示例
@NotNull 值不能为 null(可以是空串、空集合) Long userId; // 数据库必传主键
@NotEmpty 字符串/集合/数组 必须有 ≥1 个元素 List<String> tags; // 至少选一个标签
@NotBlank 字符串去掉前后空格后长度 >0 String username; // 用户名不能全空格

📏 长度 / 大小校验

注解 一句话场景 示例
@Size(min=,max=) 字符串、集合、数组长度区间 String nickname; // 2~16 个字符
@Length(min=,max=)(Hibernate 扩展) 专对字符串做字符级校验 String idCard; // 18 位身份证
@Min/@Max 数字下限 / 上限 int age; // 1~120
@DecimalMin/@DecimalMax 支持 BigDecimal 及字符串形式 BigDecimal price; // ≥0.01
@Positive / @PositiveOrZero 严格正数 / 非负数 int stock;
@Negative / @NegativeOrZero 严格负数 / 非正数 BigDecimal discount;

📧 格式 / 正则校验

注解 一句话场景 示例
@Email 宽松 Email 格式 String email;
@Pattern(regexp="") 自定义正则 String phone; // 国内 11 位手机号
@URL 合法 http/https 地址 String homepage;

🔐 布尔 / 时间 / 容器专用

注解 一句话场景 示例
@AssertTrue 必须为 true(常用于协议勾选) boolean acceptTerms;
@AssertFalse 必须为 false boolean isDeleted; // 逻辑删除字段
@Past / @PastOrPresent 必须是过去 / 过去或现在 Date birthday;
@Future / @FutureOrPresent 必须是将来 / 将来或现在 Date deliveryDate;
@Digits(integer=,fraction=) 最大整数位 & 小数位 BigDecimal fee; // 最多 5 位整数 2 位小数

🆔 Hibernate-Extra(最常用 4 个)

注解 一句话场景 示例
@Range(min=,max=) 数字/字符串长度一站式区间 int verifyCode; // 1000~9999
@UniqueElements 集合内元素不可重复 List<Long> roleIds;
@CreditCardNumber 通过 Luhn 校验的信用卡号 String cardNo;
@UUID 必须是 UUID 格式 String orderUuid;

🌰 完整 Demo(Spring Boot 2.7+)

java 复制代码
@RestController
@RequestMapping("/user")
@Validated   // ① 别忘了在类上加
public class UserController {

    @PostMapping("/register")
    public String register(@Valid @RequestBody RegisterCmd cmd) {
        return "OK";
    }
}

@Data
public class RegisterCmd {

    @NotBlank(message = "用户名不能为空")
    @Length(min = 3, max = 16, message = "用户名 3~16 位")
    private String username;

    @Email(message = "邮箱格式不正确")
    @NotBlank
    private String email;

    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误")
    private String phone;

    @Min(18) @Max(60)
    private Integer age;

    @NotEmpty
    @Size(max = 3, message = "最多选 3 个标签")
    private List<@UniqueElements String> tags;

    @AssertTrue(message = "必须同意用户协议")
    private boolean accept;
    /**
     * 目标
     */
    @NotNull(message = "目标不能为空")
    @DecimalMax(value = "99999999.99", message = "月目标不能大于99999999.99")
    @Digits(integer = 8, fraction = 2, message = "月目标整数部分最多8位,小数部分最多2位")
    private BigDecimal target;
}

启动后,如果参数非法,Spring 会自动返回:

java 复制代码
{
  "timestamp": "2025-12-12T08:30:00",
  "status": 400,
  "error": "Bad Request",
  "message": "用户名 3~16 位",
  "path": "/user/register"
}
相关推荐
凤山老林7 小时前
Spring Boot 集成 Sa-Token 实现高可用权限认证:登录鉴权、动态路由权限与接口防重放实战
spring boot·后端·sa-token·bootstrap
Wx-bishekaifayuan9 小时前
springboot桂味美食分享系统40540-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
墨神谕11 小时前
RabbitMQ 从入门到实战:核心原理、消息模型、可靠性机制与 Spring Boot 实战
spring boot·rabbitmq·java-rabbitmq
威哥爱编程11 小时前
【AI全栈12-12】Spring Boot 3.x → 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·spring boot·后端
威哥爱编程11 小时前
【AI全栈12-11】Spring Boot 把 AI 接口真正上线扛量:限流 / 降级 / 可观测
java·spring boot·后端
小蒜学长11 小时前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务
做个文艺程序员11 小时前
MQ第07篇:Java SaaS多租户消息隔离实战:RabbitMQ VHost+RocketMQ Tag+命名空间架构
spring boot·rabbitmq·rocketmq·saas·多租户
需要82612 小时前
Spring Boot 启动流程:run() 里到底发生了什么
java·spring boot·后端
凤山老林13 小时前
Spring Boot 集成 Spring Modulith:搭一个能拆微服务的模块化单体
spring boot·spring·微服务
今年下半年14 小时前
【Spring Boot】集成 Elasticsearch:中文分词与关键字高亮对接文档
spring boot·elasticsearch·中文分词