我想在数据更新后重新加载/刷新我的资源包。
我的ResourceBundle实现基于db,这里是代码:
public class DatabaseResourceBundle extends ResourceBundle {
private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("ADAEcommerceEjbPU");
private EntityManager _entityManager = factory.createEntityManager();
private Map<String, String> _values = new HashMap<>();
protected final static String BUNDLE_NAME = "com.infomaxgroup.adaecommerce.bundles";
private final static Logger LOGGER = Logger.getLogger(DatabaseResourceBundle.class.getName());
private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
protected Control DB_CONTROL = new DBControl();
/**
* Public constructor setting the parent bundle
*/
public DatabaseResourceBundle() {
LOGGER.log(Level.FINE, "DatabaseResourceBundle()");
setParent(ResourceBundle.getBundle(BUNDLE_NAME,
FacesContext.getCurrentInstance().getViewRoot().getLocale(), DB_CONTROL));
}
public DatabaseResourceBundle(Locale locale) {
LOGGER.log(Level.FINE, "DatabaseResourceBundle(Locale locale)");
setParent(ResourceBundle.getBundle(BUNDLE_NAME, locale, DB_CONTROL));
}
@Override
protected Object handleGetObject(String key) {
LOGGER.log(Level.FINE, "handleGetObject() Locale {0} Key: {1} ", new Object[]{locale.toString(), key});
return _values != null ? _values.get(key) : parent.getObject(key);
}
@Override
public Enumeration<String> getKeys() {
LOGGER.log(Level.FINE, "getKeys() Parent Locale {0} ", parent.getLocale());
return parent.getKeys();
}
/**
* The Control Callback.
*
* @see
* http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.Control.html
*/
protected class DBControl extends Control {
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
LOGGER.log(Level.INFO, "reload {0} ", reload);
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;
}
@Override
protected Object[][] getContents() {
if (locale == null) {
locale = Locale.ITALY;
}
TypedQuery<ResourceEntity> query = _entityManager.createNamedQuery("ResourceEntity.findForLocale", ResourceEntity.class);
query.setParameter("locale", locale.getLanguage());
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;
}
}
}
}
当我更新数据并调用DatabaseResourceBundle.clearCache()时,我看到下一个请求调用该方法:
MyResources.getContents()
如果我调试返回的数据
Object[][] all
这里我看到了更新的数据,但在JSF页面上我仍然看到旧数据,看起来JSF使用缓存数据。
如何在JSF页面中看到更新的数据?
非常感谢...
答案 0 :(得分:0)
问题已通过以下步骤解决:
1)修改(插入,更新,删除)任何ResourceEntity后我调用
DatabaseResourceBundle.clearCache();
2)如果我想刷新JSF资源标签,我会调用此代码(建议的代码来自:How to reload resource bundle in web application?):
ApplicationResourceBundle applicationBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("msg");
Field field = null;
try {
field = applicationBundle.getClass().getDeclaredField("resources");
} catch (NoSuchFieldException | SecurityException ex) {
Logger.getLogger(UserRegistrationController.class.getName()).log(Level.SEVERE, null, ex);
}
if (field != null) {
field.setAccessible(true);
Map<Locale, ResourceBundle> resources = null;
try {
resources = (Map<Locale, ResourceBundle>) field.get(applicationBundle);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(UserRegistrationController.class.getName()).log(Level.SEVERE, null, ex);
}
if (resources != null) {
resources.clear();
}
}
希望这会有所帮助......