一、介绍

1.1 国际化信息

国际化信息也称为本地化信息 。 Java 通过 java.util.Locale 类来表示本地化对象,它通过 “语言类型” 和 “国家/地区” 来创建一个确定的本地化对象 。举个例子吧,比如在发送一个具体的请求的时候,在header中设置一个键值对:"Accept-Language":"zh",通过Accept-Language对应值,服务器就可以决定使用哪一个区域的语言,找到相应的资源文件,格式化处理,然后返回给客户端。

1.2 MessageSource

Spring 定义了 MessageSource 接口,用于访问国际化信息。

getMessage(String code, Object[] args, String defaultMessage, Locale locale)
getMessage(String code, Object[] args, Locale locale)
getMessage(MessageSourceResolvable resolvable, Locale locale)
属性说明
code国际化资源中的属性名。
args传递格式化串占位符所用的运行期参数,当在资源找不到对应属性名时,会返回defaultMessage参数所指定的默认信息。
locale表示本地化对象。
resolvable封装了属性名、参数数组以及默认信息的大类。

二、基础使用

2.1 简单使用

在Java中,通过java.util.Locale类表示本地化对象,它通过语言类型和国家/地区等元素来确定创建一个本地化对象 。Locale对象表示具体的地理,时区,语言,政治等。我们可以通过以下方法,获取本地系统的语言,国家等信息;以及获取代表指定地区的语言,国家信息Local对象。当然你也可以调用 Locale.getAvailableLocales() 方法查看所有可用的Local对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class LocalTest {

public static void main(String[] args) {
Locale defaultLocale = Locale.getDefault();
Locale chinaLocale = Locale.CHINA;
Locale usLocale = Locale.US;
Locale usLocale1 = new Locale("en", "US");
System.out.println(defaultLocale);
System.out.println(defaultLocale.getLanguage());
System.out.println(defaultLocale.getCountry());
System.out.println(chinaLocale);
System.out.println(usLocale);
System.out.println(usLocale1);
}

}

结果输出

zh_CN
zh
CN
zh_CN
en_US
en_US

我们一般会将不同的语言的属性值存放在不同的配置文件中,ResourceBundle类可以根据指定的baseName和Local对象,就可以找到相应的配置文件,从而读取到相应的语言文字,从而构建出ResourceBundle对象,然后我们可以通过ResourceBundle.getString(key)就可以取得key在不同地域的语言文字了。

2.2 Properties配置

Properties配置文件命名规则:baseName_local.properties

假如baseName为i18n,则相应的配置文件应该命名为如下:

默认的配置文件:i18n.properties
中文的配置文件:i18n_zh_CN.properties
英文的配置文件:i18n_en_US.properties

当我们这样命名生成文件后,idea也会帮我们识别这是个国际化配置包,自动转换成如下的模式:

当然变成如上模式的时候,我们再需要添加配置文件,直接在包右键new就可以了

我们也可以在如上标记的地方进行快速添加

我们通过如下方式,就可以获取相应语言环境下的信息了,如下:

1
2
3
4
5
6
7
8
9
        chinaLocale = Locale.CHINA;
ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n", chinaLocale);
String userName = resourceBundle.getString("userName");
System.out.println(userName);

usLocale = Locale.US;
resourceBundle = ResourceBundle.getBundle("i18n", usLocale);
userName = resourceBundle.getString("userName");
System.out.println(userName);

输出

吴丹阳
wno704

三、springboot中的使用

3.1 服务端转码

3.1.1 服务配置

在application.yml中进行配置

1
2
3
spring:
messages:
basename: i18n

3.1.2 编码

然后编写测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
public class TestResource {

@Autowired
private MessageSource messageSource;

@GetMapping("test")
public String test() {
Locale locale = LocaleContextHolder.getLocale();
String userName = messageSource.getMessage("userName", null, locale);
System.out.println(userName);
return userName;
}

}

3.1.3 测试

测试如下结果:

注意:获取客户端的语言环境Locale对象,即取的请求头Accept-Language键的值来判断,我们也可以自定义请求头键,来获取语言标识。

3.2 页面语言切换

3.2.1 配置

修改 i18n.properties:

1
2
3
4
5
login.password=Password
login.remember=Remember Me
login.reset=Rest
login.submit=Sign
login.username=Username

i18n_en_US.properties:

1
2
3
4
5
login.password=Password
login.remember=Remember Me
login.reset=Rest
login.submit=Sign
login.username=Username

i18n_zh_CN.properties:

1
2
3
4
5
login.password=密码
login.remember=记住我
login.reset=重置
login.submit=登录
login.username=用户名

3.2.2 自定义语言环境解析器

我们自定义语言环境解析器,然后在引入到WebMvc配置类中,来替代原有的语言环境解析器。我们只需要实现LocaleResolver接口即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
//获取请求中的语言参数
String language = httpServletRequest.getParameter("l");
Locale locale = Locale.getDefault();//如果没有就是用默认的
//如果请求的连接携带了国际化的参数
if (!StringUtils.isEmpty(language)){
//zh-CN
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0], split[1]);
}
return locale;
}

@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

}
}

将自定义的语言环境解析器,加入SpringMvc自动配置类中

在自动配置类中需要将自定义的MyLocaleResolver类取代WebMvcAutoConfiguration中对应的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
}
//自定义国际化组件就生效了
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}

}

3.2.3 编写测试页面

首先需要引入

1
2
3
4
        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

然后编写测试页面controller

1
2
3
4
5
6
7
8
9
@Controller
public class LoginController {

@RequestMapping("/login")
public String index() {
return "login";
}

}

编写测试页面 login.hrml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>[[#{login.title}]]</title>
<link rel="stylesheet" th:href="@{/css/login.css}" type="text/css">
</head>
<body>
<div class="login-page">
<div class="form">
<span>[[#{login.title}]]</span>
<hr/>
<input type="text" th:placeholder="#{login.username}" name="username" required="required"/>
<input type="password" th:placeholder="#{login.password}" name="password" required="required"/>
<button onclick="login()" th:text="#{login.submit}"></button>
<button onclick="login()" th:text="#{login.reset}"></button>
<div style="margin-left: 100px;">
<a href="#" th:href="@{/login(l='zh_CN')}">中文</a>
<a href="" th:href="@{/login(l='en_US')}">English</a>
</div>
</div>
</div>
</body>
</html>

测试如下结果:

浏览器打开: http://127.0.0.1:8080/login

点击English切换英文