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.properties
和messages_zh_CN.properties
两个文件。
messages.properties
这个是默认的配置,其他的则是不同语言环境下的配置。这个文件一定不能少。
2、自定义文件目录配置错误,配置中没有写文件名前缀messages
。
我解决完第一个问题后,还有一个问题就是,我把这些语言文件放到默认目录/resources
目录下是好使的,可以根据报文头中的语言信息(或参数信息)返回不同语言的文本。
但是一旦我自定义文件位置,就又出现文章开头的错误。
搞了很久才发现(如果想debug源码,可参考这篇文章),
如果你的语言资源文件目录如下图:
那么,你的配置仅仅是这样不对的(如下错误示例):
spring.messages.basename=static/i18nspring.messages.encoding=UTF-8
正确的配置应该是这样的(如下正确示例):
spring.messages.basename=static/i18n/messagesspring.messages.encoding=UTF-8
中间用.
分割也可以,spring会将.
替换成/
(如下正确示例)
spring.messages.basename=static.i18n.messagesspring.messages.encoding=UTF-8
spring.messages.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;@RestControllerpublic class HelloController {@AutowiredMessageSource messageSource;@GetMapping("/hello")public String hello() {return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale());}}
zh_CN结果
en_US结果