Spring boot基础: 国际化

在Spring Boot中,国际化是通过MessageSourceLocalResolver两个核心接口来实现。

Spring Boot提供了自动配置类来简化国际化的配置,其中最重要的配置类是MessageSourceAutoConfiguration LocaleCharsetMappingAutoConfiguration

MessageSourceAutoConfiguration是一个关键的自动配置类,用于配置MessageSource

 @Configuration
@ConditionalOnMissingBean(MessageSource.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnProperty(prefix = "spring.messages", name = "basename")
public class MessageSourceAutoConfiguration {

    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        if (StringUtils.hasText(properties.getBasename())) {
            messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
                    StringUtils.trimAllWhitespace(properties.getBasename()));
        }
        if (properties.getEncoding() != null) {
            messageSource.setDefaultEncoding(properties.getEncoding().name());
        }
        messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
        messageSource.setCacheMillis(properties.getCacheMillis());
        return messageSource;
    }

    @Configuration
    @ConditionalOnNotWebApplication
    static class BaseConfiguration {

        @Bean
        public static MessageSourceInitializer messageSourceInitializer() {
            return new MessageSourceInitializer();
        }

    }

    @Configuration
    @ConditionalOnWebApplication
    static class WebConfiguration {

        @Bean
        public MessageSourceInitializer messageSourceInitializer() {
            return new MessageSourceInitializer();
        }

    }

}

以上代码主要注册了一个MessageSource的实例,通过一些列的spring.messages.*参数就可以完成自动配置。

MessageSourceProperties中包含以下几个重要的参数:

 // 要扫描的国际化文件名,默认为messages, 即在resources资源目录下建立message_xx.properties资源文件,可以通过逗号指定多个,如果不指定包名,则默认classpath跟目录下搜索
 private String basename = "messages";

 // 编码  默认为UTF8
 private Charset encoding = StandardCharsets.UTF_8;

 // 国际化资源文件被加载后的缓存时间,默认单位为秒,如果不指定则为永久缓存
 @DurationUnit(ChronoUnit.SECONDS)
 private Duration cacheDuration;

 // 找不到当前语言的资源文件时是否降级为当前操作系统的语言对应的资源文件,默认为true.  例如无法加载中文语言包messages_zh_CN.properties, 则加载系统默认的文件messages.properties
 private boolean fallbackToSystemLocate = true;

配置使用国际化

国际化支持包含在了spring boot自动配置核心包中了,所以不需要单独引入, 引入spring boot web包即可

```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
```

<p>`application.yml`配置:
```
spring:
messages:
basename: langs/common, langs/index
mvc:
locale: zh_CN
```

<p>文件目录:</p>
<p>```
resources:
langs:
common.properties
common_zh_CN.properties
index.properties
index_zh_CN.propertites
```
themeleaf模板引入

```
<title th:text="#{title}"></title>
...
<span th:text="#{index.wecome}"></span>
```

代码中使用:

@Controller
public class IndeController {
    @Autowired
    private MessageSource messageSource;

    @GetMapping("/wecome")
    public String wecome() {
        return messageSource.getMessage("index.wecome", null, LocaleContextHolder.getLocale());
    }
}

切换国际化

根据选择的语言进行切换, 注册一个LocaleResolver区域解析器和区域拦截器:

 @Slf4j
 @Configuration
 public class WebConfig implements WebMvcConfigurer {
      /**
       * Locale 默认设置为英文
       * @return
       */
     @Bean
     public LocaleResolver localeResolver() {
         SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
         sessionLocaleResolver.setDefaultLocale(Locale.US);
         return sessionLocaleResolver;
     }

     @Override
     public void addInterceptors(InterceptorRegistry) {
         registry.addInterceptor(localeChangeInterceptor());
     }

     private LocaleChangeInterceptor localeChangeInterceptor() { 
         LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
         localeChangeInterceptor.setParamName("lang");
         return localeChangeInterceptor;
     }
 }

发表回复

您的电子邮箱地址不会被公开。