跳至正文
-
关注
IT极限技术分享汇

ITmax

IT极限技术分享汇

ITmax

  • 首页
  • 商店
  • 我的帐户
  • 结账
  • 购物车
  • 首页
  • 商店
  • 我的帐户
  • 结账
  • 购物车
关

搜索

技术分享

【Spring】@Size 无法拦截null的原因

作者 leo
2025年1月20日 1 分钟阅读
0

问题复现

在构建 Web 服务时,我们一般都会对一个 HTTP 请求的 Body 内容进行校验,例如我们来看这样一个案例及对应代码。

当开发一个学籍管理系统时,我们会提供了一个 API 接口去添加学生的相关信息,其对象定义参考下面的代码:

import lombok.Data;
import javax.validation.constraints.Size;
@Data
public class Student {
    @Size(min = 1, max = 10)
    private String name;
    private short age;
}

如上代码所示,我们想针对学生的姓名进行一个判断,不能为空,并且长度为1-10。

然后,我们以下面的 JSON Body 做测试:

{
  "name": "",
  "age": 10,
  "phone": {"number":"12306"}
}

测试结果符合我们的预期,但是假设更进一步,用下面的 JSON Body(去除 name 字段)做测试呢?

{
  "age": 10,
  "phone": {"number":"12306"}
}

我们会发现校验失败了。这结果难免让我们有一些惊讶,也倍感困惑:@Size(min = 1, max = 10) 都已经要求最小长度为 1 了,难道还只能约束空字符串(即“”),不能约束 null?

案例分析

如果我们稍微留心点的话,就会发现其实 @Size 的 Javadoc 已经明确了这种情况,参考下图:

image.png

如图所示,”null elements are considered valid” 很好地解释了约束不住 null 的原因。当然纸上得来终觉浅,我们还需要从源码级别解读下 @Size 的校验过程。

这里我们找到了完成 @Size 约束的执行方法,参考 SizeValidatorForCharSequence#isValid 方法:

public boolean isValid(CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) {
    if ( charSequence == null ) {
        return true;
    }
    int length = charSequence.length();
    return length >= min && length <= max;
}

如代码所示,当字符串为 null 时,直接通过了校验,而不会做任何进一步的约束检查。

问题修正

关于这个问题的修正,其实很简单,我们可以使用其他的注解(@NotNull 或 @NotEmpty)来加强约束,修正代码如下:

@NotEmpty
@Size(min = 1, max = 10)
private String name;

完成代码修改后,重新测试,你就会发现约束已经完全满足我们的需求了。

https://segmentfault.com/a/1190000046037910

作者

leo

关注我
其他文章
上一个

Seata 源码

下一个

今日,字节发布全新 AI IDE:Trae! 它将成为最懂中文开发者 AI IDE

暂无评论!成为第一个。

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Copyright 2026 — IT极限技术分享汇. 备案号:浙ICP备17006560号-2