You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC集成Freemarker本地化消息异常:空用户名提示缺失短名正常

Spring MVC + Freemarker 校验消息部分失效问题排查与解决

看起来你遇到的是个典型的校验消息配置不匹配问题——空值校验的俄文消息找不到,但长度校验能正常显示。咱们一步步拆解原因,再给出解决办法:

核心原因分析

1. 校验注解的消息码规则不匹配

Spring的校验注解(比如@NotBlank/@NotNull/@Size)会生成一套默认的消息码优先级:

  • 优先找 {注解名}.{表单对象名}.{字段名}(比如NotBlank.userForm.username)
  • 找不到就 fallback 到 {注解名}.{字段名}(比如NotBlank.username)
  • 再找不到就用 {注解名}(比如NotBlank)
  • 如果你的注解手动指定了message="{Required}",那会直接找Required这个键,不会走上面的优先级

你的情况是:

  • 长度校验(@Size)正常,说明Size.userForm.username或者Size键在俄文消息文件里存在
  • 空值校验提示找不到Required,要么是你注解里写了message="{Required}"但俄文文件里没这个键,要么是默认的NotBlank/NotNull系列键没配置

2. 消息源配置或文件问题

  • 消息文件命名/位置不对:比如俄文消息文件应该叫messages_ru.properties,放在src/main/resources下(classpath根目录),如果文件名错了或者路径不对,Spring读不到
  • 编码问题:俄文消息文件必须用UTF-8编码,否则会出现读取失败或乱码
  • 消息源配置缺失:比如没设置defaultEncoding="UTF-8",或者basename没指向正确的消息文件前缀

3. Freemarker页面的错误渲染方式

如果页面里没有用Spring提供的spring.message()宏来解析错误消息,而是手动拼接,可能会跳过Spring的消息解析逻辑,导致找不到对应locale的消息。

具体解决步骤

第一步:检查实体类的校验注解

先看你的UserForm类里username字段的校验代码,比如:

// 错误示例:手动指定了message="{Required}",但消息文件里没这个键
@NotBlank(message = "{Required}")
@Size(min = 6, message = "{Size.userForm.username}")
private String username;

// 推荐写法:用默认的注解消息码,让Spring自动匹配
@NotBlank
@Size(min = 6)
private String username;

如果是第一种手动指定{Required}的情况,直接在俄文消息文件里加Required=Введите обязательное поле;如果是默认写法,就加NotBlank.userForm.username=Имя пользователя не может быть пустым(或者通用的NotBlank=Поле не может быть пустым)。

第二步:修复消息配置文件

打开messages_ru.properties,添加对应俄文消息:

# 针对username字段的非空校验
NotBlank.userForm.username=Имя пользователя не может быть пустым
# 通用非空校验(可选,作为fallback)
NotBlank=Поле не может быть пустым
# 你已经配置好的长度校验
Size.userForm.username=Имя пользователя должно содержать не менее 6 символов

注意:文件编码必须设为UTF-8,否则俄文会乱码。

第三步:确认消息源配置正确

检查WebConfig里的ReloadableResourceBundleMessageSource配置,确保:

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    // 指向classpath下的messages前缀文件(messages.properties、messages_ru.properties等)
    messageSource.setBasenames("classpath:messages");
    // 必须设置UTF-8编码,支持俄文
    messageSource.setDefaultEncoding("UTF-8");
    // 可选:关闭系统locale fallback,强制使用指定的locale
    messageSource.setFallbackToSystemLocale(false);
    return messageSource;
}

第四步:检查Freemarker页面的错误渲染

确保页面里导入了Spring的FTL宏,并使用spring.message()来解析错误:

<#import "/spring.ftl" as spring>

<#if bindingResult.hasErrors()>
    <div class="error-container">
        <#list bindingResult.fieldErrors as error>
            <p class="error-text">${spring.message(error)}</p>
        </#list>
    </div>
</#if>

不要手动拼接错误消息,让Spring的消息源自动根据当前locale解析对应的消息码。

第五步:验证消息文件是否被正确打包

检查项目编译后的target/classes目录下,是否存在messages_ru.properties,如果没有,说明文件位置不对,需要调整到src/main/resources下。


内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:16:30