Java OpenResty Spring Spring Boot MySQL Redis MongoDB PostgreSQL Linux Android Nginx 面试 小程序 Arthas JVM AQS juc Kubernetes Docker 诊断工具


Spring Boot i18n 国际化

Spring Boot i18n IDEA 大约 5908 字

IDEA 插件

Resources Bundle Editor,方便查看和编辑多个i18n文件。

Accept-Language

Accept-Language请求头格式:

含义:,隔开,;后跟权重,q表示权重,取值范围:0-1,没有q表示q=1

浏览器默认会携带该请求头发起请求。

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

Java自带解析Accept-Language

List<Locale.LanguageRange> parse = Locale.LanguageRange.parse("zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");

Tomcat中解析Accept-Language

// org.apache.tomcat.util.http.parser.AcceptLanguage
List<AcceptLanguage> parse = AcceptLanguage.parse(new StringReader("zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"));

AcceptHeaderLocaleResolver

Spring Boot中自带的AcceptHeader解析器,默认注入:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    @Override
    @Bean
    @ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME) // LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
    public LocaleResolver localeResolver() {
        if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.webProperties.getLocale());
        }
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.webProperties.getLocale());
        return localeResolver;
    }
}

MessageSource

注入配置

@AutoConfiguration
@ConditionalOnMissingBean(name = AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME, search = SearchStrategy.CURRENT)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Conditional(ResourceBundleCondition.class)
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {

    private static final Resource[] NO_RESOURCES = {};

    @Bean
    @ConfigurationProperties(prefix = "spring.messages")
    public MessageSourceProperties messageSourceProperties() {
        return new MessageSourceProperties();
    }

    @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());
        Duration cacheDuration = properties.getCacheDuration();
        if (cacheDuration != null) {
            messageSource.setCacheMillis(cacheDuration.toMillis());
        }
        messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
        messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
        return messageSource;
    }
}

初始化流程:

public class DispatcherServlet extends FrameworkServlet {
    @Override
    protected void onRefresh(ApplicationContext context) {
        initStrategies(context);
    }

    protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

    private void initLocaleResolver(ApplicationContext context) {
        try {
            this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
            if (logger.isTraceEnabled()) {
                logger.trace("Detected " + this.localeResolver);
            }
            else if (logger.isDebugEnabled()) {
                logger.debug("Detected " + this.localeResolver.getClass().getSimpleName());
            }
        }
        catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default.
            this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
            if (logger.isTraceEnabled()) {
                logger.trace("No LocaleResolver '" + LOCALE_RESOLVER_BEAN_NAME +
                        "': using default [" + this.localeResolver.getClass().getSimpleName() + "]");
            }
        }
    }
}

Locale

public static void main(String[] args) {
    System.out.println(Locale.getDefault().getCountry());
    System.out.println(Locale.getDefault().getDisplayCountry());
    System.out.println(Locale.getDefault().getLanguage());
    System.out.println(Locale.getDefault().getDisplayLanguage());
    System.out.println(Locale.getDefault().getDisplayName());
    System.out.println(Locale.getDefault().getScript());
    System.out.println(Locale.getDefault().getDisplayScript());
    System.out.println(Locale.getDefault().getVariant());
    System.out.println(Locale.getDefault().getDisplayVariant());
    System.out.println(Locale.getDefault().getISO3Country());
    System.out.println(Locale.getDefault().getISO3Language());
}

输出

CN
中国
zh
中文
中文 (简体,中国)
Hans
简体


CHN
zho

Locale中的常量:

public static void main(String[] args) {
    System.out.println(Locale.ENGLISH);
    System.out.println(Locale.UK);
    System.out.println(Locale.US);
    System.out.println(Locale.CHINA);
    System.out.println(Locale.PRC);
    System.out.println(Locale.TAIWAN);
    System.out.println(Locale.CHINESE);
    System.out.println(Locale.SIMPLIFIED_CHINESE);
    System.out.println(Locale.TRADITIONAL_CHINESE);
}

输出:

en
en_GB
en_US
zh_CN
zh_CN
zh_TW
zh
zh_CN
zh_TW

Spring Boot中获取Locale

RequestContext.getLoale()

LocaleContextHolder

参考文档

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language

阅读 760 · 发布于 2023-03-05

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb

扫描下方二维码关注公众号和小程序↓↓↓

扫描二维码关注我
昵称:
随便看看 换一批