idea资源包下创建资源包_资源包技巧和最佳实践
idea資源包下創建資源包
今天是資源捆綁日。 通常,這是Java中最著名的國際化機制(i18n)。 使用它應該很容易。 但是,弄污雙手時會出現許多小問題。 如果您有相同的想法,則此文章適合您。基本
java.util.ResourceBundle定義了用于訪問Java中翻譯的標準化方法。 它們包含特定于語言環境的資源。 資源束屬于其成員具有相同基本名稱的族,但是其名稱還具有其他標識組件的組件
他們的語言環境。 族中的每個資源束都包含相同的項目,但是這些項目已針對該資源束所代表的語言環境進行了翻譯。 這些是鍵/值對。 這些鍵唯一地標識捆綁軟件中特定于語言環境的對象。
最基本的示例使用以下知識:
Messages.properties
Messages_de.properties Messages_en.properties
如果您需要在應用程序中查詢包,則只需調用
ResourceBundle bundle = ResourceBundle.getBundle("Messages");方法并查詢返回的包:
bundle.getString("welcome.message");如果您想在此處使用哪種語言環境,那是對的。 String構造函數隱式使用Locale.getDefault()解析語言。 那可能不是您想要的。 所以你應該ResourceBundle bundle =
ResourceBundle.getBundle("Messages", locale);檢索捆綁軟件后,您將無法設置語言環境。 每個ResourceBundle都有一個定義的語言環境。
命名的東西
?
關于命名的一些想法。 用其內容命名捆綁屬性。 您可以通過簡單地將它們命名為“ Messages”和“ Errors”等來采用更通用的方式。但是,每個子系統或組件也可以具有捆綁軟件。 無論您需要什么。 要維護內容,要輸入大量條目并不容易。 因此,任何類型的上下文拆分都會使開發人員感到高興。 捆綁軟件屬性文件等效于類。 相應地命名。 進一步,您應該找到一個用于命名密鑰的通用系統。 根據為屬性文件選擇的拆分,還可能在密鑰中引入某種子系統或組件名稱空間。 頁面前綴也是可能的。 明智地考慮一下,并加以解決。 您的目標是盡可能減少密鑰重復。
封裝
?
如您所見,您經常使用包的字符串表示形式。 這些實際上是文件名(或更好的類名),您可以通過一個簡單的枚舉來更好地封裝所有內容:
有了這個你就可以寫
ResourceBundle bundle = ResourceBundle.getBundle(MESSAGES.getBundleName()); Java Server Faces和ResourceBundle
?
要在基于jsf的應用程序中使用資源包,您只需在faces-config.xml中定義它們,并使用xhtml文件中的快捷方式。
JSF負責其余的工作。 那參數替換呢? 考慮如下的鍵值對:
welcome.name=Hi {0}! How are you?您可以通過f:param標簽傳遞參數:
<h:outputFormat value="#{msgs['welcome.name']}"><f:param value="Markus" /></h:outputFormat>要更改語言,您必須為當前的FacesContext實例設置特定的語言環境。 最好通過值更改偵聽器執行此操作:
public void countryLocaleCodeChanged(ValueChangeEvent e) {String newLocaleValue = e.getNewValue().toString();//loop country map to compare the locale codefor (Map.Entry<String, Object> entry : countries.entrySet()) {if (entry.getValue().toString().equals(newLocaleValue)) {FacesContext.getCurrentInstance().getViewRoot().setLocale((Locale) entry.getValue());}}} EJB中的資源包
?
JSF顯然很容易集成。 在EJB中使用這些捆綁包怎么辦? 基本上是一樣的。 您有相同的機制來使用和使用捆綁包。 您應該記住一件事。 您可能不想始終使用默認語言環境。 因此,您必須找到一種從UI向下傳遞語言環境的方法。 如果您正在考慮通過@Produces注釋@Injecting MessageBundle,則必須考慮多次。 尤其是在使用@Stateless EJB時。 這些實例被合并,您必須將語言環境傳遞給需要了解當前語言環境的任何業務方法。 通常,您可以使用參數對象或某種類型的用戶會話配置文件執行此操作。 不要將語言環境全部添加為方法簽名。
來自數據庫的資源包
?
在大多數情況下,我看到您需要從數據庫中提取密鑰。 鑒于ResourceBundle的內部工作原理(每個語言環境一個“類”),您最終不得不在自己的ResourceBundle實現中實現邏輯。 您在網絡上找到的大多數示例都是通過重寫handleGetObject(String key)方法來實現的。 我不喜歡這種方法,特別是因為我們有一個更好的方法來使用ResourceBundle.Control機制。 現在,您可以覆蓋newBundle()方法并返回自己的ResourceBundle實現。 您所要做的就是將自己的Control設置為DatabaseResourceBundle的父級:
DBControl返回MyResourceBundle,它是一個ListResourceBundle:
protected class DBControl extends Control {@Overridepublic ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)throws IllegalAccessException, InstantiationException, IOException {return new MyResources(locale);}/*** A simple ListResourceBundle*/protected class MyResources extends ListResourceBundle {private Locale locale;/*** ResourceBundle constructor with locale** @param locale*/public MyResources(Locale locale) {this.locale = locale;}@Overrideprotected Object[][] getContents() {TypedQuery<ResourceEntity> query = _entityManager.createNamedQuery("ResourceEntity.findForLocale", ResourceEntity.class);query.setParameter("locale", locale);List<ResourceEntity> resources = query.getResultList();Object[][] all = new Object[resources.size()][2];int i = 0;for (Iterator<ResourceEntity> it = resources.iterator(); it.hasNext();) {ResourceEntity resource = it.next();all[i] = new Object[]{resource.getKey(), resource.getValue()};values.put(resource.getKey(), resource.getValue());i++;}return all;}}}如您所見,這由一個entitymanager和一個簡單的ResourceEntity作為后盾,該ResourceEntity具有構建不同捆綁軟件所需的所有字段和NamedQueries。
@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Column(name = "i18n_key")private String key;@Column(name = "i18n_value")private String value;@Column(name = "i18n_locale")private Locale locale;通過將捆綁包放入私有Map <String,String>值= new HashMap <String,String>(); 在首次構建捆綁包之后,您還可以使用一種很好的方法來緩存結果。
這仍然不是最好的解決方案,因為ResourceBundles具有緩存的方式。 但我稍后可能會更詳細地探討這一點。 到現在為止,該包將被永久緩存(或至少直到下一次重新部署為止)。
改寫為語言切換
?
最后要提到的是,您還可以在此處添加一些精美的插件。 如果您已經有了JSF語言切換魔術,則可以輕松地將ocpsoft的重寫添加到您的應用程序中。 這是一種將網址中的語言編碼的簡單方法,例如http://yourhost.com/Bundle-Provider-Tricks/en/index.html 您要做的就是通過添加兩個簡單的依賴關系來向游戲添加重寫:
重寫需要您添加自己的ConfigurationProvider,這是保存重寫規則的中心位置。 執行以下操作:
public class BundleTricksProvider extends HttpConfigurationProvider {@Overridepublic Configuration getConfiguration(ServletContext context) {return ConfigurationBuilder.begin()// Locale Switch.addRule(Join.path("/{locale}/{page}.html").to("/{page}.xhtml").where("page").matches(".*").where("locale").bindsTo(PhaseBinding.to(El.property("#{languageSwitch.localeCode}")).after(PhaseId.RESTORE_VIEW)));}@Overridepublic int priority() {return 10;} }接下來是將一個名為“ org.ocpsoft.rewrite.config.ConfigurationProvider”的文件添加到您的META-INF / services文件夾,并在其中放置您的ConfigurationProvider實現的標準名稱。 最后要調整的是LanguageSwitch bean中的邏輯。 重寫不能觸發ValueChangeEvent(據我所知:)),因此您必須在調用setter時添加一些魔術來更改Locale。 就是這樣..非常簡單!
參考:我們的JCG合作伙伴 Markus Eisele在企業軟件開發和Java博客上的資源捆綁技巧和最佳實踐 。
翻譯自: https://www.javacodegeeks.com/2012/09/resource-bundle-tricks-and-best.html
idea資源包下創建資源包
總結
以上是生活随笔為你收集整理的idea资源包下创建资源包_资源包技巧和最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安全清理C盘空间如何清理电脑磁盘空间
- 下一篇: 将JINQ与JPA和H2一起使用