首页 > 解决方案 > Spring Boot LocaleChangeInterceptor 在多线程环境中的行为

问题描述

我正在使用以下类来管理我的 Spring Boot 应用程序中的本地化。

@Configuration
public class MessageConfig implements WebMvcConfigurer {

    private Logger logger = LoggerFactory.getLogger(MessageConfig.class);
    /**
     * Message source for localization.
     * @return message source.
     */
    @Bean
    public MessageSource messageSource() {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating a ResourceBundleMessageSource.");
        }
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("messages");
        source.setUseCodeAsDefaultMessage(true);
        return source;
    }

    /**
     * Utility for localization.
     * @return locale resolver.
     */
    @Bean
    public LocaleResolver localeResolver() {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating a locale resolver.");
        }
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }

    /**
     * Utility for localization.
     * @return locale change interpreter.
     */
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating a locale change interceptor.");
        }
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if (logger.isDebugEnabled()) {
            logger.debug("Adding locale change interceptor to registry.");
        }
        registry.addInterceptor(localeChangeInterceptor());
    }

}

我的应用程序根据发送到 API 的 lang URL 参数决定要使用的语言环境。

当我发送localhost:8080/api时,它会以默认语言(即英语)发送内容。如果我发送localhost:8080/api?lang=si,它会发送僧伽罗语的内容。

但是,如果我在未指定语言的情况下发送请求localhost:8080/api,我会收到上一次调用中使用的僧伽罗语内容,而不是默认语言环境。我LocaleContextHolder在服务层使用来决定输出的内容。我的理解是对 API 的每个单独调用都将由一个新线程处理。那么,即使我没有指定语言,为什么在此 API 调用中默认语言环境已更改为“si”?

标签: springmultithreadingspring-bootlocalizationlocale

解决方案


SessionLocaleResolver从用户的会话中检索语言环境。我的猜测是,一旦设置了语言环境,它就会使用之前设置的值。从文档

LocaleResolver 实现,在自定义设置的情况下使用用户会话中的语言环境属性,并回退到指定的默认语言环境或请求的接受标头语言环境。

至于为什么它不改变,可能是因为没有参数LocaleChangeInterceptor请求时没有触发。/apilang


推荐阅读