六、Spring Boot 国际化

  1. SpringBoot的自动配置
    SpringBoot自动配置好了管理国际化资源文件的组件:

    @Configuration
    @ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
    @Conditional(ResourceBundleCondition.class)
    @EnableConfigurationProperties
    @ConfigurationProperties(prefix = "spring.messages")
    public class MessageSourceAutoConfiguration {
    
        private static final Resource[] NO_RESOURCES = {};
    
        /**
         * Comma-separated list of basenames (essentially a fully-qualified classpath
         * location), each following the ResourceBundle convention with relaxed support for
         * slash based locations. If it doesn't contain a package qualifier (such as
         * "org.mypackage"), it will be resolved from the classpath root.
         */
        //我们的配置文件可以直接放在类路径下叫messages.properties;
        private String basename = "messages";
       
        /**
         * Message bundles encoding.
         */
        private Charset encoding = Charset.forName("UTF-8");
    
        /**
         * Loaded resource bundle files cache expiration, in seconds. When set to -1, bundles
         * are cached forever.
         */
        private int cacheSeconds = -1;
    
        /**
         * Set whether to fall back to the system Locale if no files for a specific Locale
         * have been found. if this is turned off, the only fallback will be the default file
         * (e.g. "messages.properties" for basename "messages").
         */
        private boolean fallbackToSystemLocale = true;
    
        /**
         * Set whether to always apply the MessageFormat rules, parsing even messages without
         * arguments.
         */
        private boolean alwaysUseMessageFormat = false;
        //为容器添加了ResourceBundleMessageSource 组件
        @Bean
        public MessageSource messageSource() {
            ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
            if (StringUtils.hasText(this.basename)) {
                //设置国际化资源文件的基础名(去掉语言国家代码的)
                messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
                        StringUtils.trimAllWhitespace(this.basename)));
            }
            if (this.encoding != null) {
                messageSource.setDefaultEncoding(this.encoding.name());
            }
            messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
            messageSource.setCacheSeconds(this.cacheSeconds);
            messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
            return messageSource;
        }
    
    
  2. 国际化

    1. 编写国际化配置文件,抽取页面需要显示的国际化消息
      六、Spring Boot 国际化_第1张图片

    2. 在SpringBoot的配置文件中使用spring.messages前缀配置国际化:

        spring:
       	 messages:
          	basename: i18n.login
      
    3. 页面示例

      
      
      
          
          
          
          
          Signin Template for Bootstrap
          
          
          
          
      
      
      
      	
      
      
      

      注意实例中的国际化引入语法:
      使用的是#{…}语法,可以参考Thymeleaf中第四章Standard Expression Syntax中4.1Messages讲解,如下图.
      六、Spring Boot 国际化_第2张图片

    4. 启动项目测试效果, 效果图如下
      浏览器中文状态下:
      六、Spring Boot 国际化_第3张图片
      浏览器英文状态下(浏览器切换语言为英语)
      六、Spring Boot 国际化_第4张图片

    5. 如果在浏览器为中文状态下中文乱码了,可以进行下图设置(这种方式仅对当前项目有效,如想对所有项目有效,请进行如下操作: file --> Other Srttings --> default Setting… 在进行下图设置):
      六、Spring Boot 国际化_第5张图片

  3. 如何通过按钮进行国际化转换?
    六、Spring Boot 国际化_第6张图片

    1. SpringBoot对资源国际化解析原理

      @Bean
      @ConditionalOnMissingBean
      @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
      public LocaleResolver localeResolver() {
      	//如果指定了spring.mvc.locale,就返回FixedLocaleResolver。如果 spring.mvc.locale没有指定,那么就返回一个AcceptHeaderLocaleResolver 。
      	//AcceptHeaderLocaleResolver 的作用就是根据请求头 带来的 区域信息 进行国际化
      	if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
      		return new FixedLocaleResolver(this.mvcProperties.getLocale());
      	}
      	AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
      	localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
      	return localeResolver;
      }
      

      AcceptHeaderLocaleResolver 中的 resolveLocale()方法

      public Locale resolveLocale(HttpServletRequest request) {
              Locale defaultLocale = this.getDefaultLocale();
              if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
                  return defaultLocale;
              } else {
              	//从请求头重获取区域信息
                  Locale requestLocale = request.getLocale();
                  List supportedLocales = this.getSupportedLocales();
                  if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
                      Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
                      if (supportedLocale != null) {
                          return supportedLocale;
                      } else {
                          return defaultLocale != null ? defaultLocale : requestLocale;
                      }
                  } else {
                      return requestLocale;
                  }
              }
          }
      

      之前实例(浏览器语言为中文的情况下)发出去的请求信息:
      六、Spring Boot 国际化_第7张图片
      (浏览器语言为中文的情况下)发出去的请求信息:
      六、Spring Boot 国际化_第8张图片

      1. 编辑 LocaleResolver

        import org.springframework.util.StringUtils;
        import org.springframework.web.servlet.LocaleResolver;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.util.Locale;
        
        /**
         * Created by RM on 2018/9/30.
         *
         * 可以在链接上携带区域信息
         */
        public class MyLocalResolver implements LocaleResolver{
        
            //解析区域信息
            @Override
            public Locale resolveLocale(HttpServletRequest httpServletRequest) {
                String l = httpServletRequest.getParameter("l");
                //默认使用系统的区域信息
                Locale Locale = java.util.Locale.getDefault();
                //如果请求中有设置, 就用设置请求中的区域信息
                if(!StringUtils.isEmpty(l)){
                    String[] split = l.split("_");
                    Locale = new Locale(split[0],split[1]);
                }
                return Locale;
            }
        
            //设置区域信息
            @Override
            public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
        
            }
        }
        
      2. 容器中添加 编辑的 LocaleResolver组件

        @Configuration
        public class MyMvcConfig extends WebMvcConfigurerAdapter {
         	@Bean
            public LocaleResolver localeResolver(){
                return new MyLocalResolver();
            }
        }
        

你可能感兴趣的:(Spring,Boot)