Internationalization, or I18N, why is it called that? Because internationalization is called i18n, with 18 letters between I and n. If our application is internationalized, it can easily switch between different language environments. The most common one is the switch between Chinese and English. Internationalization is also quite common.
In Spring, passed AcceptHeaderLocaleResolver provides support for internationalization, developers through a simple configuration, can directly use the internationalization functions in project.
This support is further simplified in Spring Boot, where it is also possible to implement internationalization in a few lines of code. Songo will talk about internationalization in Spring Boot.
First of all, we need to explain that internationalization in the project often needs support from various aspects, such as internationalization in the back end and internationalization in the front page. Only with common collocation can we truly realize the function of internationalization. In this paper, I will first introduce the internationalization of Spring Boot, then introduce the internationalization of Vue, and finally apply the combination of the two to our VHR project. Therefore, there may be a total of three articles, and this is the first one.
1. Basic use
Spring, along the lines of the Boot and Spring support for the internationalization, the default is done through AcceptHeaderLocaleResolver parser, the parser, By default, the accept-language field in the request header determines the environment to which the current request belongs and gives an appropriate response.
So internationalization in Spring Boot can be done without configuration.
Start by creating a normal Spring Boot project and adding web dependencies. After the project is successfully created, the default internationalization configuration files are placed in the Resources directory, so we directly create four test files in that directory as follows:
- Our message file is created directly in the resources directory. There will be an extra Resource Bundle in the IDEA presentation. Don’t worry about this.
- Messages. properties this is the default configuration, the others are for different languages, en_US is English (US), zh_CN is simplified Chinese, and zh_TW is traditional Chinese (there is a complete language abbreviation table in the appendix at the end of this article).
After the four files are created, the first one can be left empty by default, and the other three can be filled with the following contents respectively:
messages_zh_CN.properties
User. name= jiangnan a little rainCopy the code
messages_zh_TW.properties
User. name= Jiangnan a little rainCopy the code
messages_en_US.properties
user.name=javaboy
Copy the code
Once configured, we can go straight to work. Where values are needed, simply inject the MessageSource instance.
MessageSource that needs to be configured in Spring is no longer configured, Spring will Boot by org. Springframework. Boot. Autoconfigure. Context. MessageSourceAutoConfiguration do we configure a MessageSource automatically Instance.
Create a HelloController as follows:
@RestController
public class HelloController {
@Autowired
MessageSource messageSource;
@GetMapping("/hello")
public String hello(a) {
return messageSource.getMessage("user.name".null, LocaleContextHolder.getLocale()); }}Copy the code
In HelloController, we can inject the MessageSource instance directly and call the getMessage method of the instance to retrieve the value of the variable. The first argument is to retrieve the key of the variable. The second argument is to retrieve the value if there is a placeholder in the value. You can pass in arguments from here, and the third argument just passes in an instance of Locale, which is equivalent to the current Locale.
Then we can call this interface directly.
By default, the accept-language of the request header is used to configure the current environment when the interface is invoked. I tested this using POSTMAN, with the following results:
As you can see, I set accept-language to zh-cn in the request header, so I get simplified Chinese. If I set zh-TW, I will get traditional Chinese:
Isn’t it Easy?
2. Customize the switchover
For those who feel that switching parameters in the request header is not convenient, you can also customize the parsing method. For example, parameters can be placed in the address bar as common parameters. You can perform the following operations to meet your requirements.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
registry.addInterceptor(interceptor);
}
@Bean
LocaleResolver localeResolver(a) {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
returnlocaleResolver; }}Copy the code
In this configuration, we first provide a SessionLocaleResolver as an example, the instance will replace the default AcceptHeaderLocaleResolver, Unlike AcceptHeaderLocaleResolver by request header to determine the current environmental information, SessionLocaleResolver will save the Locale for the client to the HttpSession object, It can also be modified (this means that the front-end sends the current environment information to the browser once and the browser does not have to tell the server the current environment information as long as the session is valid).
We also configured an interceptor that intercepts requests for parameters whose key is lang (locale if not configured), which specifies the current environment.
Once the configuration is complete, start the project with the following access:
We specify the current environment information by adding lang to the request. This only needs to be specified once, that is, the next request does not need to take the lang parameter with the session unchanged, and the server already knows about the current environment.
3. Other customization
By default, our configuration file is in the Resources directory. If you want to customize it, you can do so, for example, in the resources/i18n directory:
However, this way the system does not know where to load the configuration file, which requires additional configuration in application.properties (note that this is a relative path) :
spring.messages.basename=i18n/messages
Copy the code
In addition, there are some encoding format configuration, etc., as follows:
spring.messages.cache-duration=3600
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=true
Copy the code
Spring.messages. cache-duration Specifies the cache expiration time of messages files. If this parameter is not specified, the cache remains valid.
The spring. Messages. fallback-to-system-locale property is a bit more magical, and there is no clear answer online, until I look at the source code for a while.
The function of the attribute in the org. Springframework. Context. Support. AbstractResourceBasedMessageSource# getDefaultLocale effective method:
protected Locale getDefaultLocale(a) {
if (this.defaultLocale ! =null) {
return this.defaultLocale;
}
if (this.fallbackToSystemLocale) {
return Locale.getDefault();
}
return null;
}
Copy the code
As you can see from this code, if this property is true, the current system resource file is searched by default, otherwise null is returned, and the system default messages.properties file is eventually called.
4. The appendix
I have collected a list of language abbreviations to share with you:
language | Referred to as” |
---|---|
Simplified Chinese (China) | zh_CN |
Traditional Chinese (Taiwan, China) | zh_TW |
Traditional Chinese (Hong Kong, China) | zh_HK |
English (Hong Kong, China) | en_HK |
English (US) | en_US |
English (UK) | en_GB |
English (Global) | en_WW |
English (Canada) | en_CA |
English (Australia) | en_AU |
English (Irish) | en_IE |
English (Finland) | en_FI |
Finnish (Finland) | fi_FI |
English (Denmark) | en_DK |
Danish (Denmark) | da_DK |
English (Israel) | en_IL |
Hebrew (Israel) | he_IL |
English (South Africa) | en_ZA |
English (India) | en_IN |
English (Norway) | en_NO |
English (Singapore) | en_SG |
English (New Zealand) | en_NZ |
English (Indonesia) | en_ID |
English (Philippines) | en_PH |
English (Thailand) | en_TH |
English (Malaysia) | en_MY |
English (Arabic) | en_XA |
Hangul (Korean) | ko_KR |
Japanese (Japan) | ja_JP |
Dutch (Netherlands) | nl_NL |
Dutch (Belgium) | nl_BE |
Portuguese (Portuguese) | pt_PT |
Portuguese (Brazil) | pt_BR |
French (France) | fr_FR |
French (Luxembourg) | fr_LU |
French (Swiss) | fr_CH |
French (Belgium) | fr_BE |
French (Canada) | fr_CA |
Spanish (Latin America) | es_LA |
Spanish (Spanish) | es_ES |
Spanish (Argentina) | es_AR |
Spanish (US) | es_US |
Spanish (Mexico) | es_MX |
Spanish (Colombia) | es_CO |
Spanish (Puerto Rico) | es_PR |
German (German) | de_DE |
German (Austria) | de_AT |
German (Swiss) | de_CH |
Russian (Russia) | ru_RU |
Italian (Italian) | it_IT |
Greek (Greek) | el_GR |
Norwegian (Norway) | no_NO |
Hungarian (Hungary) | hu_HU |
Turkish (Turkish) | tr_TR |
Czech (Czech Republic) | cs_CZ |
Slovenian | sl_SL |
Polish (Polish) | pl_PL |
Swedish (Swedish) | sv_SE |
Spanish (Chile) | es_CL |