2013-08-04 48 views
1

我想在数据更新后重新加载/刷新我的资源包。GlassFish 3.1.2上的JSF Reload资源包

我的资源包的实现是基于数据库,这里的代码:

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

Glassfish 3.1.2查看问题标题;) – giates

+0

Ouch,您的权利,只专注于文本... 所以我不确定这是否是我已经看到的东西,但它可能注入资源注释。不确定这是否可以使用基于db的资源包。 那些资源可以重新加载jndi查找:https://blogs.oracle.com/chengfang/entry/how_to_inject_and_look –

回答

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(); 
    } 
    } 

希望这有助于...