[英]Failed to get country specific Localized response
我有一个spring boot应用程序,我们正在尝试支持多种语言和国家/地区。
这些是我们现在计划支持的代码。 en,es,fr,en-gb,es-mx,zh,ja。
我正在努力获取一些字段以响应本地化。 当我在本地(eclipse)中运行应用程序并检查邮递员的响应时,我可以看到它正在拾取特定于国家/地区的文件并正确地给出响应,但是当我将更改推送到AWS服务器时它不是,它只是获取特定于语言的文件并忽略国家/地区代码。
例如,如果我将Accept-Language设置为da,es-MX; q = 0.8我期望es-MX中的响应(我们不支持da)但它只是在es中给出响应(我有es和es-MX文件)并忽略国家代码MX。
但是,如果我将Accept-Language作为fr,es-MX; q = 0.8,它将获取messages_fr.properties文件,并以法语给出响应,这是我所期望的。
以下是我的课程。
@Configuration
@ComponentScan("com.hsf")
@EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter {
@Value("${spring.application.name}")
String appName;
@Bean
public LocaleResolver localeResolver() {
return new SmartLocaleResolver();
}
@Bean
public DispatcherServlet dispatcherServlet() {
final DispatcherServlet servlet = new DispatcherServlet();
servlet.setDispatchOptionsRequest(true);
return servlet;
}
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:i18n/messages");
// If true, the key of the message will be displayed if the key is not
// found, instead of throwing an exception
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
// The value 0 means always reload the messages to be developer friendly
messageSource.setCacheSeconds(10);
return messageSource;
}
}
此类解析Accept-Language标头并设置Locale。
public class SmartLocaleResolver extends AcceptHeaderLocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
try {
List<LanguageRange> list = Locale.LanguageRange.parse(request.getHeader("Accept-Language"));
if (!list.isEmpty()) {
for (LanguageRange s : list) {
if (ApplicationConstants.LOCALE.contains(s.getRange())) {
return Locale.forLanguageTag(s.getRange());
}
}
}
} catch (IllegalArgumentException e) {
throw e;
}
return request.getLocale();
}
}
我的ApplicationConstants类中有以下常量
public static final List<String> LOCALE = Collections
.unmodifiableList(Arrays.asList("en", "es", "fr", "es-mx", "zh", "ja"));
这是MessageHandler类
@Component
public class MessageHandler {
@Autowired
private MessageSource messageSource;
public String localizeMessage(String errorCode, Object args[]) {
Locale locale = LocaleContextHolder.getLocale();
String message = messageSource.getMessage(errorCode, args, locale);
return message;
}
public String localizeMessage(String errorCode) {
return localizeMessage(errorCode, null);
}
}
有什么想法吗?
看来你只是重新实现了Locale的lookup()方法:
List<Locale> locales = Arrays.asList(new Locale("en"),
new Locale("es"),
new Locale("fr"),
new Locale("es", "MX"),
new Locale("zh"),
new Locale("ja"));
List<Locale.LanguageRange> ranges = Locale.LanguageRange.parse("da,es-MX;q=0.8");
Locale best = Locale.lookup(ranges, locales);
System.out.println("best = " + best); // prints best = es_MX
ranges = Locale.LanguageRange.parse("fr,es-MX;q=0.8");
best = Locale.lookup(ranges, locales);
System.out.println("best = " + best); // prints best = fr
有几种方法可以实现正确的区域设置查找方法(顺便提一下,遵循i18n最佳实践)。
一种方法是在您尝试时“手动”解析标题。
但请注意, HttpServletRequest从其超类派生出一个奇特的方法,即ServletRequest#getLocales() 。
我的观点是,您将收到已经解析的优先级枚举区域设置。 顺便说一句,我肯定会使用HashSet来比较区域设置(出于性能原因)。
足够说话:
public class SmartLocaleResolver extends AcceptHeaderLocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
List<Locale> locales = Collections.list(request.getLocales());
return getBestMatchingOrDefault(locales);
}
private Locale getBestMatchingOrDefault(List<Locale> locales) {
Optional<Locale> maybeLocale = locales.stream()
.filter(locale -> ApplicationConstants.LOCALE.contains(locale))
.findFirst();
return maybeLocale.orElse(ApplicationConstants.DEFAULT_LOCALE);
}
}
在这种情况下,需要修改ApplicationConstants
类:
public static final Set<Locale> LOCALE = Collections.unmodifiableSet(
new HashSet<Locale>(
Arrays.asList(Locale.ENGLISH,
Locale.forLanguageTag("es"),
Locale.FRENCH,
Locale.forLanguageTag("es-MX"),
Locale.JAPANESE,
Locale.forLanguageTag("zh-Hans"),
Locale.PRC,
Locale.CHINESE)));
public static final Locale DEFAULT_LOCALE = Locale.ENGLISH; // or something else?
关于中文的一个词。 有两种中文口味 - 简体中文(zh-Hans)和繁体中文(zh-Hant)。 最好不要混合它们。 我不确定将简体中文版本作为默认中文版本服务是否是个好主意。 好吧,也许是,但我怀疑。 我会特别使用zh-Hans和zh-CN(即使这意味着我会在CI构建期间复制同一个文件)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.