Spring Boot 基于Sping Boot 中的Accept-Language检索区域设置

abithluo  于 2023-01-17  发布在  Spring
关注(0)|答案(7)|浏览(143)

我有一个SpringBoot(2.1.3.RELEASE)应用程序,它使用Jersey来定义(RESTful)端点,我尝试根据用户代理发送的区域设置来读取和传播一些消息。
我已经配置了这些bean:

@Bean
public LocaleResolver localeResolver() {
  final AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
  resolver.setSupportedLocales(Arrays.asList(Locale.GERMANY, Locale.US));
  resolver.setDefaultLocale(Locale.ENGLISH);
  return resolver;
}

@Bean
public MessageSource messageSource() { // Not sure if this is needed
  final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
  messageSource.setBasenames("classpath:/messages");
  messageSource.setUseCodeAsDefaultMessage(true);
  messageSource.setCacheSeconds(5);
  return messageSource;
}

...以及捆绑包(../src/main/resources/内),如:messages.properties(回退)、messages_en_US.propertiesmessages_de_DE.properties等。
现在的挑战是,我不确定如何"读取"用户代理发送的locale,以便正确地从bundle读取消息。我注入了一个MessageSource ms,并通过编程读取如下消息:

final Locale locale = ???
ms.getMessage("message.duplicate-token", null, locale);

有线索吗?
我试过LocaleContextHolder.getLocale(),但它总是en_US。如果我硬编码getMessage调用的相应语言环境,我就能够检索到正确的消息。所以我知道设置/配置在大多数情况下都是有效的。
客户端使用Accept-Language报头和如下值发送区域设置:de-DEen-US等等。

cyej8jka

cyej8jka1#

您需要添加一个LocaleChangeInterceptor并按如下所示配置bean:更多信息请参考Spring Boot internationalization

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
    lci.setParamName("lang");
    return lci;
}

如果只想使用“Accept-Language”标头,则可以扩展AcceptHeaderLocaleResolver并自定义:

package com.deb.demo.config;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

public class CustomLocaleResolver extends AcceptHeaderLocaleResolver {

    List<Locale> LOCALES = Arrays.asList(new Locale("en"),new Locale("es"),new Locale("fr"));

  @Override
  public Locale resolveLocale(HttpServletRequest request) {
     if (StringUtils.isEmpty(request.getHeader("Accept-Language"))) {
         return Locale.getDefault();
       }
     List<Locale.LanguageRange> list = Locale.LanguageRange.parse(request.getHeader("Accept-Language"));
     Locale locale = Locale.lookup(list,LOCALES);
      return locale;
     }
}
eh57zj3b

eh57zj3b2#

我在用豆子

@Bean
  public LocaleResolver localeResolver() {
    AcceptHeaderLocaleResolver slr = new AcceptHeaderLocaleResolver();
    slr.setDefaultLocale(Locale.UK);
    return slr;
  }

然后又是一个

@Bean
  public LanguageUtil languageUtil() {
    return new LanguageUtil();
  }

private Locale getLocale() {
    return LocaleContextHolder.getLocale();
  }

  public String getLocalizedMessage(String messageKey) {
    return messageSource.getMessage(messageKey, null, getLocale());
  }

标头保存在LocaleContextHolder中,您可以在需要时使用它。

3mpgtkmj

3mpgtkmj3#

创建自定义AcceptHeaderLocaleResolver

public class AcceptHeaderResolver extends AcceptHeaderLocaleResolver {

    List<Locale> LOCALES = Arrays.asList(new Locale("en"), new Locale("ar"));

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String headerLang = request.getHeader("Accept-Language");
        return headerLang == null || headerLang.isEmpty()
                ? Locale.getDefault()
                : Locale.lookup(Locale.LanguageRange.parse(headerLang), LOCALES);
    }

}

不要忘记在@Configuration文件中使用它

@Bean
public LocaleResolver sessionLocaleResolver() {
    AcceptHeaderResolver localeResolver = new AcceptHeaderResolver();
    return localeResolver;
}
zpqajqem

zpqajqem4#

如果您想在REST控制器级别上获得这个特性,您可以直接在REST方法中获得locale示例。

@GetMapping("/status")
public ResponseEntitiy<String> getStatus(final Locale locale) {

}
n53p2ov0

n53p2ov05#

您创建的LocaleResolver bean只能在SpringMVC中使用,而不能在Jersey容器中使用,使用LocaleResolver的是Spring的DispatcherServlet。
因此,区域上下文保持器。getLocale();将返回不同的本地值,具体取决于是在Jersey控制器还是Spring MVC控制器中调用。

3pvhb19x

3pvhb19x6#

不需要扩展AcceptHeaderLocaleResolver,创建bean定义如下:

@Bean
public LocalResolver localeResolver() {
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setSupportedLocales(Arrays.asList(new Locale("fa"), new Locale("en")));
    localeResolver.setDefaultLocale(new Locale("fa"));
    return localeResolver;
}
yrdbyhpb

yrdbyhpb7#

你必须在你的API端点中添加Accept-Language标头来获得所需的语言环境输出。然后你必须添加以下配置来解析和设置来自传入请求的Accept-Language标头值。

@Configuration
public class I18NConfiguration {

    @Value("${i18n.locale.default:en-US}")
    private String defaultLocale;

    @Value("#{'${i18n.locale.supported: }'.split(',\\s*')}")
    private List<String> supportedLocales;

    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver();
        acceptHeaderLocaleResolver.setDefaultLocale(Locale.forLanguageTag(defaultLocale));

        if (supportedLocales != null && !supportedLocales.isEmpty()) {
            List<Locale> localeList = supportedLocales.stream().map(Locale::forLanguageTag).collect(Collectors.toUnmodifiableList());
            acceptHeaderLocaleResolver.setSupportedLocales(localeList);
        }
        return acceptHeaderLocaleResolver;
    }
}

相关问题