2016-05-04 16 views
3

私は春の起動アプリケーションを持っており、複数の言語と国をサポートしようとしています。国ごとの対応に失敗しました。ローカライズされた応答

これらは、私たちが今のサポートを計画しているコードです。 ja、es、fr、en-gb、es-mx、zh、ja。

私は、ローカライズさに応じて、いくつかのフィールドを得ることに取り組んでいます。 それは、私は(日食)私の地元でアプリケーションを実行して、郵便配達からの応答をチェックすると、私はそれが国の特定のファイルを拾って、正しく応答を与えていることがわかりますが、私はAWSサーバへの私の変更をプッシュするとき、それはありません言語固有のファイルを取得し、国別コードを無視するだけです。

たとえば、私がAccept-Languageをda、es-MX、q = 0.8とすると、es-MX(daはサポートしていません)の応答が期待されますが、 esとes-MXの両方のファイルがあります)、国コードMXは無視されます。

しかし、私はFRとして言語を受け入れている場合、-MXはES; 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

でなければなりません。どうもありがとう。投稿したコードで返されたLocaleを印刷すると、MXではなくmxとして印刷されました。なぜ私はMXの代わりにmxでファイル名を保持したのですか?あなたのコードから、es_MXとして印刷されていることがわかります。メッセージの名前をmessages_es_MX.propertiesに変更していました。再度、感謝します。 – Arun

1

(国際化のベストプラクティスを、次の方法祝によって)正しいロケールルックアップメソッドを実装するには、いくつかの方法があります。
1つの方法は、試みたようにヘッダーを "手動で"解析することです。
しかし、HttpServletRequestServletRequest#getLocales()でそのスーパークラスから1つの空想の方法を導き出すことに注意してください。
ローカライズされているのは、すでに解析済みの優先度が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)の2つの味があります。それらを混ぜ合わせないことが最善です。デフォルトの中国語版として簡体字中国語を提供することをお勧めしますか?まあ、それかもしれないが、私は疑問がある。 zh-Hansとzh-CNを特に使用します(たとえCIビルド中に同じファイルをコピーしても)。

+0

ありがとうございます。 – Arun

関連する問題