Spring 国际化遇到的坑org.springframework.context.NoSuchMessageException: No message found under code ‘xxx.xxxx’ for locale ‘zh_CN’

背景

以前做的项目客户群体只有国内的客户,从来没有考虑过语言文字的问题。
这次有一个需求的返回内容,要根据客户设置的语言返回不同的语言。
尝试使用了以后,结果发现怎么都不好使,一直报的一个错误如下:

org.springframework.context.NoSuchMessageException: No message found under code 'user.name' for locale 'zh_CN'.
	at org.springframework.context.support.DelegatingMessageSource.getMessage(DelegatingMessageSource.java:76) ~[spring-context-5.3.23.jar:5.3.23]

详细用法

至于i18n具体用法就不详细说明了,网上也很多,这里推荐一个我感觉写的挺好的一篇。
大佬链接

错误原因

我出现这个错误主要是两个原因:

1、没有创建messages.properties文件。

我只创建了messages_en_US.propertiesmessages_zh_CN.properties两个文件。
messages.properties 这个是默认的配置,其他的则是不同语言环境下的配置。这个文件一定不能少。

2、自定义文件目录配置错误,配置中没有写文件名前缀messages

我解决完第一个问题后,还有一个问题就是,我把这些语言文件放到默认目录/resources目录下是好使的,可以根据报文头中的语言信息(或参数信息)返回不同语言的文本。
但是一旦我自定义文件位置,就又出现文章开头的错误。
搞了很久才发现(如果想debug源码,可参考这篇文章),
如果你的语言资源文件目录如下图:
语言资源文件
那么,你的配置仅仅是这样不对的(如下错误示例):

spring.messages.basename=static/i18n
spring.messages.encoding=UTF-8

正确的配置应该是这样的(如下正确示例):

spring.messages.basename=static/i18n/messages
spring.messages.encoding=UTF-8

中间用.分割也可以,spring会将.替换成/(如下正确示例)

spring.messages.basename=static.i18n.messages
spring.messages.encoding=UTF-8

spring.messages.basename的值不仅仅是目录,还包括文件的前缀

最后来一张完整的图和结果
basename
controller部分代码

package com.example.i18n.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @Autowired
    MessageSource messageSource;
    @GetMapping("/hello")
    public String hello() {
        return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale());
    }
}

zh_CN结果
在这里插入图片描述
en_US结果
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐