[英]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.