2016-05-04 55 views
3

我有一個彈簧啓動應用程序,我們正在嘗試支持多種語言和國家/地區。無法獲得國家/地區特定的本地化響應

這些是我們現在計劃支持的代碼。 zh,es,fr,en-gb,es-mx,zh,ja。

我正在努力獲取一些字段以響應本地化。 當我在本地(eclipse)運行應用程序並檢查郵遞員的響應時,我可以看到它正在拾取特定國家/地區的文件並正確給出響應,但是當我將更改推送到AWS服務器時,它不是,它是隻拾取語言特定的文件並忽略國家代碼。例如,如果我將Accept-Language設置爲da,es-MX; q = 0.8,我期望在es-MX中的響應(我們不支持da),但它只是給出es中的響應(I同時具有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); 
    } 

} 

對這個有什麼想法?

回答

2

看來你只是重新實現區域設置的查詢()方法:

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 
+0

這看起來更好一些,但由於某些原因,它仍然會拾取messages_es.properties文件而不拾取messages_es_mx.properties。但正如我前面提到的在我的本地工作(當我從日食運行)。這是我的請求da中的頭部,es-MX; q = 0.8 – Arun

+1

您的文件應該命名爲messages_es_MX.properties,而不是messages_es_mx.properties –

+0

它的工作原理。非常感謝。當我打印與代碼返回的語言環境我發佈它打印爲MX而不是MX。這就是爲什麼我用mx而不是MX保存文件名。從你的代碼中,我看到它被打印爲es_MX,我將它重命名爲messages_es_MX.properties並且它工作正常。再次感謝。 – Arun

1

有實現(下列關於國際化的最佳實踐的方式祝賀)正確的語言環境查找方法幾個方面。
一種方法是像您嘗試的那樣「手動」解析標題。
但請注意HttpServletRequest從它的超類派生出一種奇特的方法,那就是ServletRequest#getLocales()
我的觀點是,您將收到已解析的Locale優先Enumeration。順便說一下,我肯定會使用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構建期間複製相同的文件)。

+0

感謝您的解釋。 – Arun

相關問題