ViewScoped Bean 中 SessionScope 的 ManagedProperty - 瞬态?

Posted

技术标签:

【中文标题】ViewScoped Bean 中 SessionScope 的 ManagedProperty - 瞬态?【英文标题】:ManagedProperty of SessionScope inside a ViewScoped Bean - Transient? 【发布时间】:2012-12-20 10:56:27 【问题描述】:

我有一个这样的 JSF Beans 结构:

@ManagedBean
@ViewScoped
public class ViewBeany implements Serializable 

....
    @ManagedProperty(value='#sessionBeany)
    transient private SessionBeany sessionBeany;
...

    public getSessionBeany()  ... ;
    public setSessionBeany(SessionBeany sessionBeany)  ... ;


transient 的原因是会话 bean 有一些不可序列化的成员,无法设为可序列化。

这行得通吗? 如果没有,我该如何解决无法序列化 SesionBeany 但必须将其作为托管属性保留在视图范围 bean 下的问题?

谢谢!

【问题讨论】:

如果您不受限制,您也可以将您的 STATE_SAVING_MODE 设置为 server 并避免将您的视图完全序列化到客户端 【参考方案1】:

这行不通。如果视图范围 bean 被序列化,则所有 transient 字段都将被跳过。 JSF 在反序列化后不会重新注入托管属性,因此您最终会得到一个没有会话范围 bean 属性的视图范围 bean,这只会导致 NPE。

在这个特定的构造中,最好的办法是在 getter 中引入延迟加载,并通过 getter 而不是直接字段访问来获取会话 bean。

private transient SessionBeany sessionBeany;

public SessionBeany getSessionBeany()  // Method can be private.
    if (sessionBeany == null) 
        FacesContext context = FacesContext.getCurrentInstance();
        sessionBeany = context.getApplication().evaluateExpressionGet(context, "#sessionBeany", SessionBeany.class);
    

    return sessionBeany;

【讨论】:

谢谢。我很惊讶 JSF 没有针对这个问题的“简化”解决方案,因为我想这并不罕见。 我已经想知道它是否不应该是有状态的 EJB。 EJB 作为可序列化代理注入,因此您无需担心序列化。

以上是关于ViewScoped Bean 中 SessionScope 的 ManagedProperty - 瞬态?的主要内容,如果未能解决你的问题,请参考以下文章

在 JSF 中如何以及何时销毁 @ViewScoped bean?

即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容

在 @ViewScoped bean 之间传递对象而不使用 GET 参数

@ViewScoped JSF bean 被多次初始化

p:remoteCommand 销毁 @ViewScoped 托管 bean

如何检测和删除(在会话期间)不能被垃圾收集的未使用的 @ViewScoped bean