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>

application.yml配置:

spring:
  messages:
    basename: langs/common, langs/index
  mvc:
    locale: zh_CN

文件目录:

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;
    }
}

评论

暂无已审核评论。

发表评论

评论提交后需审核,通过后才会公开显示。