@NotBlank(message = “{xxx}“) 注解中花括号的含义

【SpringBoot 实战】@NotBlank(message = "{auth.clientid.not.blank}") 花括号里的是什么?

一、问题场景

最近在看项目的登录代码 LoginBody.java,发现一个很有意思的写法:

复制代码
@NotBlank(message = "{auth.clientid.not.blank}")
private String clientId;

以前我写的校验注解都是这样的:

复制代码
@NotBlank(message = "客户端ID不能为空")
private String clientId;

为什么要用花括号 {} 包起来?直接写文案不好吗? "auth.clientid.not.blank" 这一串是啥意思?


二、答案:这是国际化(i18n)的消息配置写法

花括号 {} 包裹的内容是一个 消息键(Message Key),它的作用是:

告诉校验框架:别直接把 {auth.clientid.not.blank} 当错误文案返回,而是去国际化资源文件中查找对应 key 的实际文案。

用一张图理解:

复制代码
前端传参 clientId 为空
        │
        ▼
@NotBlank 校验失败
        │
        ▼
看到 message = "{auth.clientid.not.blank}"
        │
        ▼
去 messages_zh_CN.properties 找 key
        │
        ├── key: auth.clientid.not.blank = 认证客户端id不能为空
        │
        ▼
返回给前端:认证客户端id不能为空

三、项目中的实际配置

在 SpringBoot 项目的 resources 目录下,通常会有几个 properties 文件:

文件名 语言环境 内容示例
messages.properties 默认(中文) auth.clientid.not.blank=认证客户端id不能为空
messages_zh_CN.properties 简体中文 auth.clientid.not.blank=认证客户端id不能为空
messages_en_US.properties 英文 auth.clientid.not.blank=Auth clientid cannot be blank
messages_ja_JP.properties 日文 auth.clientid.not.blank=認証クライアントIDは空にできません

**校验框架会根据当前请求的语言(请求头 Accept-Language)自动选择对应的文件:

请求头 Accept-Language 返回的错误信息
zh-CN,zh;q=0.9 认证客户端id不能为空
en-US,en;q=0.9 Auth clientid cannot be blank
ja-JP,ja;q=0.9 認証クライアントIDは空にできません

四、两种写法的对比

写法 示例 优缺点
硬编码 @NotBlank(message = "客户端id不能为空") ✅ 写起来简单 ❌ 不支持多语言 ❌ 改文案要改 Java 代码
消息键(推荐) @NotBlank(message = "{auth.clientid.not.blank}") ✅ 支持多语言切换 ✅ 改文案只改 properties 文件 ✅ 文案统一管理,不会漏改 ❌ 多写一层配置

五、花括号语法从哪来的?

这不是 Spring 独创的,而是 **JSR-303 / JSR-380(Bean Validation)规范定义的标准语法:

语法 含义
message = "xxx" 直接返回字符串
message = "{xxx}" 去资源文件查找 key 对应的值
message = "{xxx} {yyy}" 支持拼接,两个 key 都会解析
message = "长度必须在 {min} 到 {max} 之间" 甚至可以引用注解参数

比如 @Size 注解可以这样用:

复制代码
@Size(min = 2, max = 10, message = "用户名长度必须在 {min} 到 {max} 之间")
private String username;

校验失败时会自动替换:

复制代码
用户名长度必须在 2 到 10 之间

六、SpringBoot 中怎么配置?

1. 新建国际化资源文件

resources/i18n/ 目录下(或者直接 resources/):

复制代码
resources/
├── messages.properties         # 默认
├── messages_zh_CN.properties
└── messages_en_US.properties
2. 在 application.yml 配置:
复制代码
spring:
  messages:
    basename: i18n/messages   # 如果在 i18n 目录下
    encoding: UTF-8
3. 配置 LocaleResolver(可选,基于请求头切换语言)
复制代码
@Configuration
public class I18nConfig {

    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
        resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return resolver;
    }
}

这样前端在 DTO 上直接用:

复制代码
@NotBlank(message = "{user.username.not.blank}")
private String username;

七、总结

问题 答案
{auth.clientid.not.blank} 是什么? 国际化资源文件中的 **消息 key
为什么用花括号? JSR-303 规范的语法,告诉框架去解析 key
好处是什么? 支持多语言、文案统一管理、改文案不用改代码
相关推荐
2601_962071575 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
zww89491115 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·eclipse
zww89491118 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
黑马程序员毕设9 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
木井巳9 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
白山编程大哥10 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
devpotato10 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis
xcl092510 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·spring boot·需求分析
Kyrie_kk10 小时前
Java--IO--Path文件访问
java·后端
qinqinzqq10 小时前
Maven POM 格式、Schema 与 XSD:一篇讲透
java·maven