簡體   English   中英

如何在Web應用程序中重新加載資源包?

[英]How to reload resource bundle in web application?

我有資源束作為從數據庫中讀取值的Java類。 當我更新數據庫時,我需要重新加載捆綁軟件,但我不知道如何。 有人幫忙嗎?

package model.helpers;
public class Messages_en extends ListResourceBundle {
      protected Object[][] getContents() {
            // from DB
            // ...
      }
}

鑒於我使用捆綁如下:

<f:loadBundle basename="model.helpers.Messages" var="m" />

這並非完全無關緊要。

對於一個人,僅僅通過clearCache()清除ResourceBundle並不總是產生期望的結果。 通常,您至少還需要嘗試使用上下文類加載器進行清除:

ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());

但是,這仍然不會重新加載faces-config.xml文件中定義的資源包。 至少Mojarra JSF 1.2實施在內部專用於緩存資源束。 這發生在:

FacesContext -> Application -> associate (ApplicationAssociate) -> resourceBundles (Map<String, ApplicationResourceBundle>()) -> resources (Map<Locale, ResourceBundle>) 

可以通過反射清除緩存(一天結束時,它只是Map中的一個條目),或者您可能想替換Application。 兩者都不是您平時輕松做的事情。

純粹出於開發目的,您可以使用JRebel,它可能已經了解Mojarra,並且很可能會執行上述反射技巧。

經過一些實驗之后,我來到了下面的代碼,該代碼在JBoss AS 5 / JSF 1.2上發揮了作用。 它確實將您的代碼綁定到Mojarra(導入了sun軟件包),並且由於使用了反射技巧而可能無法進行任何升級。 但是無論如何,這是代碼:

public static void reloadBundle() {

    ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());

    ApplicationResourceBundle appBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("your_bundle_name");               
    Map<Locale, ResourceBundle> resources = getFieldValue(appBundle, "resources");          
    resources.clear();
}

@SuppressWarnings("unchecked")
private static <T> T getFieldValue(Object object, String fieldName) {
    try {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return (T) field.get(object);
    } catch (Exception e) {
        return null;
    }       
}

(如有必要,將getFieldValue helper方法替換為您自己喜歡的反射util,並在適當的地方撒上異常和null處理程序)

ResourceBundle.clearCache();     

要么

Messages_en .clearCache();

調用此方法將重新加載資源,它將刷新包

您甚至可以避免在模塊中導入weld和jsf-impl類,從而獲得更多反射:

Class<?> applicationAssociateClass = Class.forName("com.sun.faces.application.ApplicationAssociate");
Method getCurrentInstance = applicationAssociateClass.getMethod("getCurrentInstance");
Object applicationAssociate = getCurrentInstance.invoke(null);
Method getResourceBundles = applicationAssociate.getClass().getMethod("getResourceBundles");
Map<String, ?> resourceBundles = (Map<String, ?>)getResourceBundles.invoke(applicationAssociate);
Object appBundle = resourceBundles.get(name);
Map<Locale, ResourceBundle> resources = getFieldValue(appBundle, "resources");
resources.clear();

(與Wildfly 10兼容)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM