我目前正在使用带有 JSF 2.0 (MyFaces) 的 Websphere 8.5。由于@ViewScoped bean 的状态保存(服务器和客户端模式),我一直面临一些问题。我有以下豆
@ManagedBean
@ViewScoped
public class BrokenBean implements Serializable {
//Problem: not synchronized with real SessionBean object
@ManagedProperty(value="#{sessionBean})
private SessionBean session;
//Problem: this gives NotSerializableException to some server generated class.
@EJB
private MyEJB myejb;
//Getter and Setter for above properties
}
@ManagedBean
@SessionScoped
public class SessionBean implements serializable{
private Integer i;
//Getter and Setter
}
//MyEJB has a method to get Counter from database
我的测试页包含
<h:outputText value="#{brokenBean.session.i}"></h:outputText>
<h:outputText value="#{brokenBean.myejb.getCounter()}"></h:outputText>
状态保存时两者都将失败。
对于SessionBean,当我进入使用BrokenBean的页面,i = 1,在另一个页面设置i = 2,使用BrokenBean的页面仍然会显示i = 1。
对于 MyEJB,这将简单地将 NotSerializableException 提供给一些可能是服务器生成的名为 "*Local*MyEJB" 的类,其中 * 代表一些我不记得准确的字符。
我使用了一种可行的解决方法,但这就像“假设是透明的”JSF 的不必要的复杂化。还有其他看起来更干净的解决方法吗?
我最终上了这门课:
@ManagedBean
@ViewScoped
public class FixedBrokenBean implements Serializable {
private transient SessionBean session;
private transient MyEJB myejb;
//I must use getters below when I access these two properties within this class
//so that getters will perform a lookup if they are null at the time I need them.
public MyEJB getMyejb() {
if (myejb == null) {
try {
InitialContext ic = new InitialContext();
myejb = (MyEJB) ic.lookup("java:global/testear/testejb/MyEJB !test.MyEJB");
} catch (NamingException e) {
e.printStackTrace();
}
}
return myejb;
}
public SessionBean getSession() {
if (session == null) {
FacesContext context = FacesContext.getCurrentInstance();
session = (SessionBean) context.getApplication().evaluateExpressionGet(context, "#{sessionBean}", SessionBean.class);
}
return session;
}
}