会话作用域内的ManagedProperty在视图作用域Bean中是瞬态的吗?

6

我有一个JSF Beans结构,类似于这样:

@ManagedBean
@ViewScoped
public class ViewBeany implements Serializable {

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

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

}
< p > transient 的原因是会话bean有一些非Serializable成员,无法将其转换为Serializable。< /p > < p >这样可以吗?
如果不行,我该如何解决无法序列化SessionBean但必须将其保留为视图范围bean的托管属性的问题?< /p > < p >谢谢!< /p >

如果没有这么多限制,您也可以将STATE_SAVING_MODE设置为server,从而避免完全将视图序列化到客户端。 - kolossus
1个回答

12

这样行不通。如果视图范围的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没有一个“简化”的解决方案来解决这个问题,因为我认为这并不是那么罕见的情况。 - Ben
2
我曾经想过它是否应该是一个有状态的EJB。EJB被注入为可序列化代理,因此您不需要担心序列化问题。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接