簡介
In computing, internationalization and localization are means of adapting computer software to different languages, regional peculiarities and technical requirements of a target locale.
術語
-
i18n
internationalization
英 [ˌɪntəˌnæʃnəlaɪ'zeɪʃn]
,國際化。由於首字母"i"和末尾字母"n"間有18個字符,所以簡稱i18n。
internationalization指為了使應用程序能適應不同的語言和地區間的變化而不作系統性的變化所采取的設計措施。
-
l10n
localization, 本地化。
由於首字母"l"和末尾字母"n"間有10個字母,所以簡稱l10n。
localization指為了使應用軟件能夠在某一特定語言環境或地區使用而加入本地特殊化部件和翻譯后文本的過程。 -
locale: 指語言和區域進行特殊組合的一個標志
一般語言_地區
可以確定一個特定類型的本地化信息。
基名_語言_地區.properties
- 語言由兩個小寫字母表示,具體代碼是由ISO-639標准定義。
- 地區由兩個大寫字母表示,由ISO-3166標准定義的。
- 基名,basename,一般是業務代碼。例如:
ValidationLogin.properties
常用配置:
-
i18n_zh_CN.properties:中國大陸的,中文語言的資源
-
i18n_en_US.properties:美國地區,英文語言的資源
-
i18n.properties:默認資源文件,如果請求相應的資源文件不存在,將使用此資源文件
JDK的支持
java.util.Local
SpringBoot的支持
-
org.springframework.context.MessageSource
public interface MessageSource { String getMessage(String var1, Object[] var2, String var3, Locale var4); String getMessage(String var1, Object[] var2, Locale var3) throws NoSuchMessageException; String getMessage(MessageSourceResolvable var1, Locale var2) throws NoSuchMessageException; }
-
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration
-
org.springframework.context.support.AbstractApplicationContext#initMessageSource
-
ResourceBundleMessageSource
-
ReloadableResourceBundleMessageSource
了解這些類,對問題排查會有幫助。
實戰
SpringBoot
提供兩種配置方式。
Java配置
重新定義org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration#messageSource
中的bean。
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
application配置
spring.messages.basename=i18n
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration#messageSource
根據配置文件,自動創建beanmessageSource
.
代碼演示
文件配置:
email.server=mail.163.com
RestController
@RestController
public class MessageSourceTestController {
@Autowired
private MessageSource messageSource;
@GetMapping("/mail")
public String getUsers() {
return messageSource.getMessage("email.server", null, Locale.CHINA);
}
}
請求接口,獲取配置文件中的值。
遇到的問題
接手一個老項目,restful
框架還是自研的,切換為springboot框架后,國際化配置遇到些問題。
整理如下。
MessageSource
null
org.springframework.context.support.AbstractApplicationContext#initMessageSource
,初始化時,沒有檢測到messageSource
Bean,會默認提供一個空的實現DelegatingMessageSource
。
解決辦法,直接實例化,一個bean。參考上文java配置
@ConditionalOnMissingBean (types: org.springframework.context.MessageSource; SearchStrategy: current) did not find any beans (OnBeanCondition)
應該是個bug,參考Spring Boot MessageSourceAutoConfiguration,實際開發中,可忽略。
debug=true
application.properties
中添加debug=true
,在應用啟動的時候,會把自動化配置、bean等信息打印出來。
2019-06-13 14:03:42.740 DEBUG 18680 --- [ main] ationConfigEmbeddedWebApplicationContext : Using MessageSource [org.springframework.context.support.ResourceBundleMessageSource: basenames=[messages/messages]]
MessageSourceAutoConfiguration matched:
- ResourceBundle found bundle URL [file:/D:/git/github/spring-boot-samples/spring-boot-sample-il8n/target/classes/messages/messages.properties] (MessageSourceAutoConfiguration.ResourceBundleCondition)
- @ConditionalOnMissingBean (types: org.springframework.context.MessageSource; SearchStrategy: current) did not find any beans (OnBeanCondition)
沒有檢測到messageSource
Bean,會默認提供一個空的實現
[2019-06-13 14:19:43.453] [main] [DEBUG] [igServletWebServerApplicationContext:739 ] - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@3f2ab6ec]