在Spring Boot微服务中,对国际化或者多种语言的支持主要通过”LocaleResolver“和(MessageSource)消息来支持。

本实例以Spring Boot 1.5.9为例,来演示Spring Boot对国际化的支持。

1. 项目结构

2. 消息文件(Properties)

HelloMessage.properties

1
msg.hello = Hello

HelloMessage_en_US.properties

1
msg.hello = Hello

HelloMessage_zh_CN.properties

1
msg.hello = 你好

3. Spring Boot 配置

a.首先我们需要在系统配置的文件指定消息路径:

1
2
3
4
spring:
messages:
encoding: UTF-8
basename: com/devnp/message/HelloMessage

b.配置”LocaleResolver“和”LocaleChangeInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
*
*/
package com.devnp.springbootinternationalizationdemo.config;

import java.util.Locale;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

/**
* @author duliu
*
*/
@Configuration
public class LocaleConfig extends WebMvcConfigurerAdapter{

/**
* 配置默认语言
* @return
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.US);

return sessionLocaleResolver;
}

/**
* 注册一个“LocaleChangeInterceptor”拦截器并将其引用到任何需要支持多种语言的处理器映射。 “paramName”是用于设置语言环境的参数值。
* @return
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");

return localeChangeInterceptor;
}

/**
* 对拦截器进行注册
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}

4. 控制器 Controller

编写一个简单的Controller根据语言来获取消息文件中的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
*
*/
package com.devnp.springbootinternationalizationdemo.web;

import java.util.Locale;

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

/**
* @author duliu
*
*/
@RestController
public class HelloController {

@Autowired
private MessageSource messageSource;

@RequestMapping("/hello")
public String index() {
Locale locale = LocaleContextHolder.getLocale();

String message = messageSource.getMessage("msg.hello", null, locale);

return message;
}
}

5. 测试

a.单元测试

HelloControllerTests.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
*
*/
package com.devnp.springbootinternationalizationdemo.web;

import java.io.UnsupportedEncodingException;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

/**
* @author duliu
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloControllerTests {

@Autowired
private WebApplicationContext context;

private MockMvc mvc;

@Before
public void before() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}

@Test
public void testIndex() throws UnsupportedEncodingException, Exception {
String enResult = this.mvc.perform(MockMvcRequestBuilders.post("/hello?language=en_US"))
.andExpect(MockMvcResultMatchers.status().isOk()).andReturn().getResponse().getContentAsString();

String zhResult = this.mvc.perform(MockMvcRequestBuilders.post("/hello?language=zh_CN"))
.andExpect(MockMvcResultMatchers.status().isOk()).andReturn().getResponse().getContentAsString();

System.out.println("enResult : " + enResult);
System.out.println("zhResult : " + zhResult);
}
}

结果:

1
2
enResult : Hello
zhResult : 你好

b.启动项目,在浏览器中输入URL

1.默认语言

2.中文语言

6. Spring Boot 更多配置

Spring Boot 在对国际化的支持主要有如下配置:

1
2
3
4
5
6
7
8
9
10
# INTERNATIONALIZATION (MessageSourceAutoConfiguration)
spring.messages.always-use-message-format=false
//是否始终应用Message文件配置为主,如果设置成true会忽略掉传入的参数。默认是false,即有参数以参数为优先
spring.messages.basename=messages
//设置消息文件路径,默认查找以message开头
spring.messages.cache-seconds=-1
// 加载的资源包文件缓存过期,以秒为单位。 设置为-1时,捆绑包将永久缓存。
spring.messages.encoding=UTF-8 //消息编码
spring.messages.fallback-to-system-locale=true
//没有找到支持的语言文件,是否使用使用系统消息文件,默认为 true

7. 代码下载

spring-boot-internationalization-demo.zip