Please indicate the original source, thank you!

HappyFeet blog

Internationalization, I understand is according to the user’s language Settings to display the corresponding language, prompt. Corresponding to the code is to return the description of the corresponding language according to the different locale. For example, the default environment is Hello in Chinese! When the language changes to English, it should display Hello! This is internationalization.

The first contact with internationalization is in the existing project, there is a ready-made internationalization configuration, there is a special class for internationalization: i18NService.java, need internationalization directly use it. Now I am assigned to do a new project in Modu, and everything needs to be configured by myself. Fortunately, I was able to complete the international configuration independently. Although it is quite simple to think about now, I still feel a great sense of achievement when I successfully completed it.


1. I18nService encapsulates the MessageSource class, adding new methods or simplifying the call chain as needed

public class I18nService {

    private final MessageSource messageSource;

    public I18nService(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    public String getMessage(String msgKey, Object[] args) {
        return messageSource.getMessage(msgKey, args, LocaleUtils.getCurrentLocale());
    }

    public String getMessage(String msgKey) {
        return messageSource.getMessage(msgKey, null, LocaleUtils.getCurrentLocale()); }}Copy the code

2, configuration,I18nServiceMessageSourceBean, which is primarily baseNames for configuring resource files; Of course, you can also use the YML attributespring.messages.basename) configuration

    @Bean
    public I18nService i18nService(a) {
        return new I18nService(messageSource());
    }

    @Bean
    public ResourceBundleMessageSource messageSource(a) {
        Locale.setDefault(Locale.CHINESE);
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasenames("i18n/messages");// name of the resource bundle
        source.setUseCodeAsDefaultMessage(true);
        source.setDefaultEncoding("UTF-8");
        return source;
    }
Copy the code

3. Multi-language resource configuration files (basenames = I18N/Messages), that is, the directory where the configuration file resides is I18N and the file prefix is messages

(1) the messages. The properties
Message. The key. The test = test! Message. Key. Hello = how are you! {0} ~Copy the code
(2) messages_en. Properties
message.key.test=test! Message. Key. Hello = hello! {0} ~Copy the code

4. Controller for test

@Controller
@RequestMapping(value = "/api")
public class HelloJavaCoderController {

    private final I18nService i18nService;

    public HelloJavaCoderController(I18nService i18nService) {
        this.i18nService = i18nService;
    }

    @GetMapping("/hello-coder")
    public ResponseEntity greeting(a) {
        return ResponseEntity.ok(i18nService.getMessage("message.key.hello".new Object[]{"JavaCoder"}));
    }

    @GetMapping("/test")
    public ResponseEntity test(a) {
        return ResponseEntity.ok(i18nService.getMessage("message.key.test")); }}Copy the code

5, Use Postman API test (start service, server.port=8888)

(1) request to http://localhost:8888/api/test and set the Accept – Languate = useful in the header, the results are as follows:

(2) request to http://localhost:8888/api/test and set the Accept – Languate = en in the header, the results are as follows:

(3) request to http://localhost:8888/hello-coder and set the Accept – Languate = useful in the header, the results are as follows:

(4) request to http://localhost:8888/hello-coder and set the Accept – Languate = en in the header, the results are as follows:

(1) (2) is a normal internationalization demonstration, (3) (4) shows that internationalization can also use placeholders to bind specific parameters at run time, by passing an Object[] args to getMessage to replace the parameters in place, using a method similar to {0}

After running it through and validating it, you want to take a look at its internal implementation (how does MessageSource read the internationalized values from the Properties file?). , took a look at the source code and debugged it, and finally learned that it loads msgKey and value in the properties file into onelookupThe first load of the HashMap cache, the cache directly behind the cache, interested students can be inPropertyResourceBundle.java:157Locale -> (msgKey -> value); locale -> (msgKey -> value);

Finally, one properties file corresponds to onePropertyResourceBundleObject.

The above code can be found on Github: spring-i18n-support