网上有很多Spring国际化的样例,但是缺少详细的样例。特别是国外网上很多是Spring MVC(Web)之类的样例,而国内稍具规模的软件开发组织都采用前后端分离的模式,所以几乎很少有易于模仿的 纯基础Spring国际化 样例。
1. 创建 Spring Boot 工程
1.1 Maven依赖
此示例以Command Line方式运行,所以依赖 spring-boot-starter,而不是 spring-boot-starter-web。
本人非常讨厌 Spring官网那种 “直接” “仅” 提供Web服务样例的入门示例!
我觉得入门就该从最简单基础的模式开始,“直接从Web服务开始”不利于新手学习。
Xml代码
<parent>
<groudId>org.sprinframework.boot</gourpId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
1.2 主方法
Java代码
package org.sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args){
SpringApplication.run(Main.class);
}
}
2. 添加国际化数据文件
国际化数据文件一般都放在 classpath 路径下。
例:(我使用的是IDEA)
messages.properties 是默认数据源文件。
该文件必须存在,否则 Spring Boot(MessageSourceAutoConfiguration)无法自动配置。
ResourceBundleCondition会检查 messages.properties 是否存在。如果不存在,则MessageSourceAutoConfiguration 这个Bean不会被创建,MessageSource这个Bean也就不会被创建。
当然,我们也可以比较hack的方式绕过这个检查。
messages_en.properties 是默认的英文数据源文件。
messages_en_US.properties 是美式英文的数据源文件。
当Spring无法从该文件找到对应数据时,会自动从messages_en.properties 中找;如果还是未找到,则从 messages.properties 中找。(其它区域语言类似)
messages_zh_CN.properties 是简体中文数据源文件。
messages_zh_TW.properties 是繁体中文数据源文件。
数据源内容示例:
greeting=Hello, {0}!
等号“=”前是数据条目的代号;等号后是数据条目的内容;“{0}”是一个占位符,我们可以用该数据条目和指定的数据动态组装出一条消息(类似 String.format 方法)
注意:
上述文件名中的下划线是非常关键的一部分,它会被用于拼接 数据源文件 的路径。
Spring Boot (MessageSourceProperties)默认的数据源文件编码格式为 UTF-8。如果你的数据源文件时其它编码格式,如 GBK,那就可能出现乱码。
3. 指定国际化数据文件路径
在Spring Boot的默认配置文件 application.yml 中配置:
Yaml代码
spring:
messages:
basename: i18n/messages
basename 会用于拼接 数据源文件 的路径。
如果想让 Spring Boot 自动载入新的数据源文件,则可以配置 cache-duration 来指定缓存有效时间(与 basename 同级)。
例 cache-duration:30m 表示有效期为30分钟,超过该有效期后,Spring Boot 将重新读取数据源文件。
4. 使用国际化数据
Java代码
package org.sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;
import java.util.Locale;
@Component
public class Sample implements CommandLineRunner {
@Autowired
private MessageSource messageSource;
@Override
public void run(String... args) throws Exception {
String name = "赵钱孙";
String code = "greeting";
Object[] data = new Object[]{name};
String enHello = messageSource.getMessage(code, data, Locale.ENGLISH);
String usHello = messageSource.getMessage(code, data, Locale.US);
String cnHello = messageSource.getMessage(code, data, Locale.SIMPLIFIED_CHINESE);
String twHello = messageSource.getMessage(code, data, Locale.TRADITIONAL_CHINESE);
}
}
MessageSource 有三个 getMessage 方法。可根据项目需求,自行选择。
5. 我不要默认的 messages.properties !!!
很多情况下,我们都希望用 code 来代替未配置的message。
这可通过application.yml中设置 spring.messages.use-code-as-default-message 为 true 来实现。
这种情况下,messages.properties 就等同于一个空文件,因为其中的内容不会被使用。
如果你嫌空文件碍事、不顺眼,可将其删除,并以一种较为hack的方式来绕过Spring Boot对此文件(messages.properties)必须存在的限定。
具体方法就是创建一个自定的配置类,它继承自 MessageSourceAutoConfiguration,但是去除了 Condition注解。例:
Java代码
@Configuration
@ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties
public class MessageSourceConfig extends MessageSourceAutoConfiguration {
}
注意:这种hack方式显然是存在更多Spring Boot新老版本不兼容的风险。自行取舍吧。