如何在Web应用程序中重新加载资源包?

mar*_*osh 10 java jsf web-applications jsf-2

我有资源包作为Java类从数据库中读取值.当我更新数据库我需要重新加载包,但我不知道如何.有人帮忙吗?

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

在视图中我使用bundle如下:

<f:loadBundle basename="model.helpers.Messages" var="m" />
Run Code Online (Sandbox Code Playgroud)

Arj*_*jms 10

这并非完全无足轻重.

对于一个只是清除ResourceBundle通孔clearCache()并不总是产生所需的结果.通常,您至少还需要尝试清除使用上下文类加载器:

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

但是,这仍然不会重新加载faces-config.xml文件中定义的资源包.至少Mojarra JSF 1.2实现在内部私有地缓存资源包.这发生在:

FacesContext -> Application -> associate (ApplicationAssociate) -> resourceBundles (Map<String, ApplicationResourceBundle>()) -> resources (Map<Locale, ResourceBundle>) 
Run Code Online (Sandbox Code Playgroud)

可以通过反射清除此缓存(在一天结束时,它只是Map中的条目),或者您可能想要替换应用程序.两者都不是你通常轻松愉快的事情.

纯粹用于开发你可以使用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;
    }       
}
Run Code Online (Sandbox Code Playgroud)

(如果需要,用你自己喜欢的反射工具替换getFieldValue辅助方法,并在适当的地方撒上异常和空处理程序)


Jig*_*shi 5

ResourceBundle.clearCache();     
Run Code Online (Sandbox Code Playgroud)

要么

Messages_en .clearCache();
Run Code Online (Sandbox Code Playgroud)

调用此方法将重新加载资源,它将刷新捆绑包