日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

资源包技巧和最佳实践

發(fā)布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 资源包技巧和最佳实践 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
今天是資源捆綁日。 通常,這是Java中最著名的國際化機制(i18n)。 使用它應(yīng)該很容易。 但是,在弄臟手時會出現(xiàn)許多小問題。 如果您有相同的想法,則此文章適合您。

基本

java.util.ResourceBundle定義了用于訪問Java中翻譯的標(biāo)準(zhǔn)化方法。 它們包含特定于語言環(huán)境的資源。 資源束屬于其成員具有相同基本名稱的族,但是其名稱還具有標(biāo)識
他們的語言環(huán)境。 族中的每個資源束都包含相同的項目,但是這些項目已針對該資源束所代表的語言環(huán)境進行了翻譯。 這些是鍵/值對。 這些鍵唯一地標(biāo)識捆綁軟件中特定于語言環(huán)境的對象。

最基本的示例使用以下知識:
Messages.properties
Messages_de.properties Messages_en.properties

如果您需要在應(yīng)用程序中查詢包,則只需調(diào)用

ResourceBundle bundle = ResourceBundle.getBundle("Messages");

方法并查詢返回的包:

bundle.getString("welcome.message");

如果您想在此處使用哪種語言環(huán)境,那是對的。 String構(gòu)造函數(shù)隱式使用Locale.getDefault()解析語言。 那可能不是您想要的。 所以你應(yīng)該ResourceBundle bundle =

ResourceBundle.getBundle("Messages", locale);

檢索捆綁軟件后,您將無法設(shè)置語言環(huán)境。 每個ResourceBundle都有一個定義的語言環(huán)境。

命名的東西
?
關(guān)于命名的一些想法。 用其內(nèi)容命名捆綁屬性。 您可以通過簡單地將它們命名為“消息”和“錯誤”等來采用更通用的方式。但是,每個子系統(tǒng)或組件也可以具有捆綁軟件。 無論您需要什么。 要維護內(nèi)容,要輸入大量條目并不容易。 因此,任何類型的上下文拆分都會使開發(fā)人員感到高興。 捆綁軟件屬性文件等效于類。 相應(yīng)地命名。 進一步,您應(yīng)該找到一個用于命名密鑰的通用系統(tǒng)。 根據(jù)為屬性文件選擇的拆分,還可能在密鑰中引入某種子系統(tǒng)或組件名稱空間。 頁面前綴也是可能的。 明智地考慮一下,并加以解決。 您的目標(biāo)是盡量減少密鑰重復(fù)。

封裝
?
如您所見,您經(jīng)常使用包的字符串表示形式。 這些實際上是文件名(或更好的類名),您可以通過一個簡單的枚舉來更好地封裝所有內(nèi)容:

public enum ResourceBundles {MESSAGES("Messages"),ERRORS("Errors");private String bundleName; ResourceBundles(String bundleName) {this.bundleName = bundleName;}public String getBundleName() {return bundleName;}@Overridepublic String toString() {return bundleName;} }

有了這個你就可以寫

ResourceBundle bundle = ResourceBundle.getBundle(MESSAGES.getBundleName());

Java Server Faces和ResourceBundle
?
要在基于jsf的應(yīng)用程序中使用資源包,您只需在faces-config.xml中定義它們,并使用xhtml文件中的快捷方式。

<resource-bundle> <base-name>Messages</base-name> <var>msgs</var><h:outputLabel value="#{msgs['welcome.general']}" />

JSF負責(zé)其余的工作。 那么參數(shù)替換呢? 考慮如下的鍵值對:

welcome.name=Hi {0}! How are you?

您可以通過f:param標(biāo)簽傳遞參數(shù):

<h:outputFormat value="#{msgs['welcome.name']}"><f:param value="Markus" /></h:outputFormat>

要更改語言,您必須為當(dāng)前的FacesContext實例設(shè)置特定的語言環(huán)境。 最好通過值更改偵聽器執(zhí)行此操作:

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中使用這些捆綁包怎么辦? 基本上是一樣的。 您可以使用相同的機制來使用和使用捆綁包。 您應(yīng)該記住一件事。 您可能不想始終使用默認語言環(huán)境。 因此,您必須找到一種從UI向下傳遞語言環(huán)境的方法。 如果您想通過@Produces批注@Injecting MessageBundle,則必須考慮多次。 尤其是在使用@Stateless EJB時。 這些實例將合并,您必須將語言環(huán)境傳遞給需要了解當(dāng)前語言環(huán)境的任何業(yè)務(wù)方法。 通常,您可以使用參數(shù)對象或某種用戶會話配置文件來執(zhí)行此操作。 不要將語言環(huán)境全部添加為方法簽名。

來自數(shù)據(jù)庫的資源包
?
在大多數(shù)情況下,我看到您需要從數(shù)據(jù)庫中提取密鑰。 鑒于ResourceBundle的內(nèi)部工作原理(每個語言環(huán)境一個“類”),您最終不得不在自己的ResourceBundle實現(xiàn)中實現(xiàn)邏輯。 您在網(wǎng)絡(luò)上找到的大多數(shù)示例都是通過重寫handleGetObject(String key)方法來實現(xiàn)的。 我不喜歡這種方法,尤其是因為我們有一個更好的方法來使用ResourceBundle.Control機制。 現(xiàn)在,您可以覆蓋newBundle()方法并返回自己的ResourceBundle實現(xiàn)。 您所要做的就是將自己的Control設(shè)置為DatabaseResourceBundle的父級:

public DatabaseResourceBundle() {setParent(ResourceBundle.getBundle(BUNDLE_NAME,FacesContext.getCurrentInstance().getViewRoot().getLocale(), new DBControl()));}

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具有構(gòu)建不同捆綁軟件所需的所有字段和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>(); 在首次構(gòu)建捆綁包之后,您還可以使用一種很好的方法來緩存結(jié)果。

這仍然不是最好的解決方案,因為ResourceBundles具有緩存的方式。 但我稍后可能會更詳細地探討這一點。 到現(xiàn)在為止,此捆綁包將被永久緩存(或至少直到下一次重新部署為止)。

改寫為語言切換
?
最后要提到的是,您還可以在此處添加一些精美的插件。 如果您已經(jīng)有了JSF語言切換魔術(shù),則可以輕松地將ocpsoft的重寫添加到您的應(yīng)用程序中。 這是一種將網(wǎng)址中的語言編碼的簡單方法,例如http://yourhost.com/Bundle-Provider-Tricks/en/index.html 您要做的就是通過添加兩個簡單的依賴關(guān)系來向游戲添加重寫:

<dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-servlet</artifactId><version>1.1.0.Final</version></dependency><dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-integration-faces</artifactId><version>1.1.0.Final</version></dependency>

重寫需要您添加自己的ConfigurationProvider,這是保存重寫規(guī)則的中心位置。 執(zhí)行以下操作:

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實現(xiàn)的標(biāo)準(zhǔn)名稱。 最后要調(diào)整的是LanguageSwitch bean中的邏輯。 重寫不能觸發(fā)ValueChangeEvent(據(jù)我所知:)),因此您必須在調(diào)用setter時添加一些魔術(shù)來更改Locale。 就是這樣..非常簡單!

參考:來自JCG合作伙伴 Markus Eisele的Resource Bundle技巧和最佳實踐 ,位于Enterprise Software Development with Java博客上。


翻譯自: https://www.javacodegeeks.com/2012/09/resource-bundle-tricks-and-best.html

總結(jié)

以上是生活随笔為你收集整理的资源包技巧和最佳实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。