在每次完全刷新或页面重新加载时,托管Java bean都会重新初始化

时间:2014-07-22 21:49:45

标签: xpages

在我的XPage应用程序中,我使用托管Java bean( scope = application )来翻译字符串:

public class Translator extends HashMap<String,String> implements Serializable {

    private static final long serialVersionUID = 1L;
    public String language = "en";

    public Translator() { super(); this.init(null); }
    public Translator(String language) { super(); this.init(language); }

    public boolean init(String language) {
        try {           
            FacesContext context = FacesContext.getCurrentInstance();
            if (language!=null) this.language=language;
            Properties data = new Properties();

            // load translation strings from properties file in WEB-INF
            data.load(new InputStreamReader(context.getExternalContext().getResourceAsStream("WEB-INF/translations_"+this.language+".properties"),"UTF-8"));
            super.putAll(new HashMap<String,String>((Map) data));

            // serializing the bean to a file on disk > this part of the code is just here to easily test how often the bean is initialized
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\dump\\Translator_"+this.language+"_"+new Date().getTime()+".ser"));
            out.writeObject(this);
            out.close();

            return true;
        }
        catch (Exception e) { return false; }
    }

    public String getLanguage() { return this.language; }
    public boolean setLanguage(String language) { return this.init(language); }

    // special get function which is more tolerant than HashMap.get
    public String get(Object key) {
        String s = (String) key;
        if (super.containsKey(s)) return super.get(s);
        if (super.containsKey(s.toLowerCase())) return super.get(s.toLowerCase());
        String s1 = s.substring(0,1);
        if (s1.toLowerCase().equals(s1)) {
            s1=super.get(s1.toUpperCase()+s.substring(1));
            if (s1!=null) return s1.substring(0,1).toLowerCase()+s1.substring(1);
        } else {
            s1=super.get(s1.toLowerCase()+s.substring(1));
            if (s1!=null) return s1.substring(0,1).toUpperCase()+s1.substring(1);           
        }
        return s;
    }
}

我使用&#34; 扩展HashMap &#34;因为这样我只需要写&#34; $ {myTranslatorBean [&#39; someText&#39;]}&#34; (表达式语言)将翻译到我的XPage中。问题是bean在每次完全刷新或页面重新加载时重新初始化。我通过在每次初始化结束时将bean序列化到磁盘上的唯一文件来测试它。在我的其他托管Java bean(不使用&#34;扩展HashMap&#34;)中,不会发生此问题。任何人都能告诉我我的代码有什么问题吗?提前谢谢。


编辑:faces-config.xml中托管Java bean的条目如下所示:

  <managed-bean>
    <managed-bean-name>myTranslatorBean</managed-bean-name>
    <managed-bean-class>com.ic.Translator</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>

2 个答案:

答案 0 :(得分:2)

我同意David关于faces-config条目 - 如果你可以发布它,那可能会对它有所启发。

在它缺席的情况下,我会对它进行一次尝试:你是否正在使用托管资产设置&#34;语言&#34;应用程序的价值。如果你是,我怀疑运行时很有可能过度调用setLanguage(...)方法。由于您在该方法中调用this.init(...),因此也会重复运行该方法。

作为一种代码风格,您可以随意忽略,随着时间的推移,我(部分原因是由于阅读其他人的意见)已经不再直接扩展集合类以供此类使用。在这种情况下我做的是创建一个实现DataObject接口的对象,然后在内部使用HashMap来存储缓存的值。这是一个更大的行业偏好的一部分,称为“#34;继承继承&#34;:http://en.wikipedia.org/wiki/Composition_over_inheritance

答案 1 :(得分:1)

只是为了确保没有什么奇怪的 - 我建议你发布你的faces-config。我一直使用bean但没有在任何一个中扩展HashMap。您可以添加地图并仍然使用EL。

假设你有一个像“getMyMap()”这样的地图getter,那么EL可能是:

AppBean.myMap [ “的myKey”]

说实话,我通常不会使用这种语法,但我相信这有效。我给了它一个快速测试,它没有像我预期的那样工作,所以我错过了一些东西。我尝试过类似的东西: imageData.size [ “大”]。网址

我认为它对我不起作用,因为我的bean没有实现Map。我注意到你正在扩展HashMap。您可能想尝试实现它。我在这里发现了一篇有趣的帖子:http://blog.defrog.nl/2012/04/settings-bean-parameterized-method-call.html

通常我仍然使用SSJS来传递参数。这真的不是使用SSJS的结束。我将EL用于其他一切。

这是一个将对象传递给自定义控件并返回带有EL的TreeSet的示例。

值= “#{compositeData.imageSet.allImages}” &GT;

关于bean重新初始化的更大问题..这很奇怪..我不会用ApplicationScope做很多事情。但我建议你玩构造函数。我不确定你在那里调用super()得到了什么。我建议使用布尔值来运行尚未设置的布尔值的任何初始化代码。显然你然后在init代码中设置它。看看它做了什么。