5

明らかにResourceBundle、検出したファイルに構文のようなプロパティファイルが必要です。

ファイル全体(この場合はHTMLファイル)を「値」として使用したいという状況があります。これは、そのようなキーがないことを意味します。ええと、ファイル名がキーとして機能するかもしれません。

ディレクトリツリーは次のとおりです。

src/
    main/
        resources/
            html/
                content.html
                content_de.html
                content_fr.html
                content_es.html
                order.html
                order_de.html
                order_fr.html
                order_es.html

次に、現在のロケールに基づいて正しいファイルを見つけるためのロジックが必要です。html/content.html現在のロケールがドイツ語で、ファイルを探している場合は、が見つかるはずhtml/content_de.htmlです。必ずしもすぐにロードする必要はありません。Javaには既存のメカニズムがありますか?これを手動で行う必要がありますか?

いくつかの制限により、現在、サードパーティのライブラリを使用しないことを計画しています。したがって、Java 6 SEで利用可能なものがある場合は、それが最善の選択です。ただし、サードパーティのライブラリをご存知の場合は、お気軽に名前を付けてください。

編集#1:明らかな解決策は、messages.propertiesそのHTMLファイルに名前を付けるためのキーを入力することです。それはうまくいくでしょうが、それは長期的にはお尻の痛みになるかもしれません(そしてそれ以外に、これがこれに関する私たちのすべての問題を解決するとは思わない)。

編集#2:これはデスクトップアプリケーションだと言うのを忘れました。

4

3 に答える 3

1

これをより理想的にするために、ファイルの命名規則が一貫している場合(つまり、ロケールごとに、言語の2文字のプレフィックスを使用します。英語の場合は「en」、フランス語の場合は「fr」、の場合は「es」を意味します。スペイン語)、このプロセスは非常に簡単です。

クラスを使用Propertiesしてプロパティを読み取り、MessageFormat結果のプロパティから必要な適切なロケールをフォーマットするために使用します。

まず、プロパティファイルに変更を加えます。パラメータ化して、好きなものを渡すことができるようにします。

content=content_{0}.html
order=order_{0}.html

{0}、プロパティの最初のパラメータを表します。

これで、プロパティをロードして、適切なパラメータを渡すだけで済みます。

Properties prop = new Properties();
try {
    MessageFormat messageFormat = new MessageFormat("");
    String property;
    // change to suit the locale you wish to serve
    String[] param = {"en"};

    prop.load(new FileReader(new File("/full/path/to/property/file.properties")));
    property = prop.getProperty("content");
    messageFormat.applyPattern(property);
    System.out.println(messageFormat.format(param));
} catch(IOException ioex) {
    System.out.println("no property file here");
}

これは印刷されます:

content_en.html

この呼び出しを行う前に、アクセスするHTMLファイルが存在することを確認するか、これをを返す関数に変換しString、ファイルが返される前にファイルが存在することを確認してください。

于 2012-09-02T17:16:18.043 に答える
1

私が何もしていないことを示すために、「自分で」アプローチを使用した2つの試みを次に示します。

locale-postfixビルドアップとリソースの直接ロードを使用した最初の試み:

  public void attempt1(String baseName, String extension) {
    List<String> locales = buildLocaleStrings(Locale.getDefault());
    String resourceFound = null;

    for (String locale : locales) {
      String resourceName = baseName + locale + "." + extension;
      URL resource = getClass().getClassLoader().getResource(resourceName);
      if (resource != null) {
        resourceFound = resourceName;
        break;
      }
    }
    System.out.println("found #1: " + resourceFound);
  }

  private List<String> buildLocaleStrings(Locale localeBase) {
    String locale = "_" + localeBase;
    List<String> locales = new ArrayList<String>();

    while (locale.length() > 0) {
      locales.add(locale);
      locale = locale.replaceFirst("_[^_]*?$", "");
    }
    locales.add("");

    return locales;
  }

2回目の「乱用」ResourceBundleとそのtoString()

  public void attempt2(String baseName, final String extension) {
    ResourceBundle.Control control = new ResourceBundle.Control() {

      private String resourceFound = null;

      @Override
      public List<String> getFormats(String baseName) {
        return Arrays.asList(extension);
      }

      @Override
      public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, format);

        if (loader.getResource(resourceName) != null) {
          resourceFound = resourceName;
          return new ResourceBundle() {

            @Override
            public Enumeration<String> getKeys() {
              return null;
            }

            @Override
            protected Object handleGetObject(String key) {
              return null;
            }

          };
        }
        return null;
      }

      @Override
      public String toString() {
        return resourceFound;
      }
    };

    ResourceBundle.getBundle(baseName, control);

    System.out.println("found #2: " + control.toString());
  }

サンプル呼び出し:

  public void proof() {
    attempt1("html/content", "html");
    attempt2("html/content", "html");
  }

どちらも同じファイルを見つけます。

正直、どちらも好きではありません。

于 2012-09-02T20:58:55.723 に答える
0

これは古い質問ですが、まったく同じ問題に遭遇し、より洗練された解決策を見つけました。必要なのは、APIがキーの変換を解決するのと同じ方法で、ロケールからファイルへのマッピングを標準のJavaAPIに委任することです。したがって、あなたの例では、現在のロケールがfr_FRの場合、「content_fr.html」および「order_fr.html」というファイルをロードしますか?

次に、リソースバンドルファイルのセットを用意し、現在のロケールを最も近い既存のロケールに変換する変数を指定します。

ファイルtranslation.properties:

localeCode = 

ファイルtranslation_fr.properties:

localeCode = fr

ファイルtranslation_en.properties:

localeCode = en

次に、「localeCode」の値を読み取り、「content」と「.html」または「order」と「.html」と連結する必要があります。

于 2015-06-24T19:33:45.293 に答える