現在、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 の場合、i = 1 で BrokenBean を使用してページに入り、別のページで i = 2 を設定すると、BrokenBean を使用するページは引き続き i = 1 を表示します。
MyEJB の場合、これは単に「*Local*MyEJB」と呼ばれるサーバー生成クラスに NotSerializableException を与えるだけです。ここで、* は正確に覚えていない文字を表します。
私は機能する回避策を使用しましたが、それは「透過的であると仮定する」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;
}
}