一千萬個為什麽

搜索

如何避免Java ResourceBundle字符串中的重復?

我們有很多字符串包含相同的子字符串,從關於檢查日誌或如何聯系支持的句子到包含公司或產品名稱的類似品牌的字符串。重復導致了我們自己的一些問題(主要是拼寫錯誤或復制/粘貼錯誤),但它也會導致問題,因為它增加了翻譯者必須翻譯的文本量。

我提出的解決方案是這樣的:

public class ExpandingResourceBundleControl extends ResourceBundle.Control {
  public static final ResourceBundle.Control EXPANDING =
    new ExpandingResourceBundleControl();

  private ExpandingResourceBundleControl() { }

  @Override
  public ResourceBundle newBundle(String baseName, Locale locale, String format,
                                  ClassLoader loader, boolean reload)
    throws IllegalAccessException, InstantiationException, IOException {

      ResourceBundle inner = super.newBundle(baseName, locale, format, loader, reload);
      return inner == null ? null : new ExpandingResourceBundle(inner, loader);
  }
}

ExpandingResourceBundle delegates to the real resource bundle but performs conversion of {{this.kind.of.thing}} to look up the key in the resources.

每次你想要獲得其中一個,你必須去:

ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING);

這工作正常 - 一段時間。

最終發生的是一些新代碼(在我們的例子中是自動生成的代碼,它是由Matisse吐出的)查找相同的資源包而不指定自定義控件。如果你編寫一個簡單的單元測試來調用它然後沒有,這似乎是不可重現的,但它是在應用程序運行真實時發生的。不知何故, ResourceBundle 中的緩存彈出了良好的值,並用破壞的值替換它。我還沒弄清楚為什麽和Sun的jar文件是在沒有調試信息的情況下編譯的,所以調試它是一件苦差事。

我的問題:

  1. 有沒有辦法全局設置我可能不知道的默認ResourceBundle.Control?這樣可以相當優雅地解決所有問題。

  2. 是否有其他方式可以優雅地處理這類事情,或許根本沒有篡改ResourceBundle類?

最佳答案

我認為這是ResourceBundles設計運行方式的一個根本缺陷:引用其他鍵的鍵會自動違反DRY(不要重復自己)原則。我解決這個問題的方法類似於你的方法:創建一個ReflectiveResourceBundle類,它允許你使用EL表示法在消息中指定資源鍵。

錯誤的方式:

my.name.first=Bob
my.name.last=Smith
my.name.full=Bob Smith

正確的方式:

my.name.first=Bob
my.name.last=Smith
my.name.full=${my.name.first} ${my.name.last}

我已將代碼上傳到GitHub ,以便您或其他任何人可以下載它。此外,我為使用Stripes Framework的任何人添加了一些示例代碼( http://www.stripesframework.org/ )讓你快速上手。

讓它與標準JSTL fmt taglib一起工作的技巧是設置一個攔截器,用我們自己的資源替換HttpServletRequest的資源。代碼看起來像這樣:

ResourceBundle bundle = MyStaticResourceHoldingTheBundle.getBundle();
Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));

有關更多詳細信息,請查看上面鏈接中的stripes.interceptor包。

轉載註明原文: 如何避免Java ResourceBundle字符串中的重復?