Spring ViewScope Bean导致NotSerializableException

Spring ViewScope Bean导致NotSerializableException,spring,jsf,serialization,jsf-2,notserializableexception,Spring,Jsf,Serialization,Jsf 2,Notserializableexception,您好,我正在使用一个ViewScope Bean,问题是当调用它时,我得到了NotSerializableException 这是我的托管Bean的代码: @ManagedBean(name="demandesBean") @ViewScoped public class DemandesBean implements Serializable { private static final long serialVersionUID = 1L; @ManagedProperty

您好,我正在使用一个ViewScope Bean,问题是当调用它时,我得到了NotSerializableException

这是我的托管Bean的代码:

@ManagedBean(name="demandesBean")
@ViewScoped
public class DemandesBean implements Serializable {
    private static final long serialVersionUID = 1L;

    @ManagedProperty(value="#{demandeService}")
    private DemandeService demandeService; //A Spring Service

    @ManagedProperty(value="#{loginBean}")
    private LoginBean loginBean;

    private DemandeVO newDemande;

    @PostConstruct
    public void initData() {
        newDemande = new DemandeVO();
    }

    public void doAjouterDemande(ActionListener event) {
        demandeService.createDemande(newDemande, loginBean.getUsername());
        newDemande = new DemandeVO();
    }

    public List<DemandeVO> getListDemande() {
        return demandeService.getAllDemandesByUser(loginBean.getUsername());
    }

    public DemandeService getDemandeService() {
        return demandeService;
    }

    public void setDemandeService(DemandeService demandeService) {
        this.demandeService = demandeService;
    }

    public LoginBean getLoginBean() {
        return loginBean;
    }

    public void setLoginBean(LoginBean loginBean) {
        this.loginBean = loginBean;
    }

    public DemandeVO getNewDemande() {
        return newDemande;
    }

    public void setNewDemande(DemandeVO newDemande) {
        this.newDemande = newDemande;
    }
}

这个问题有解决办法吗??请帮忙

另一个问题是,默认情况下MyFaces会对状态进行序列化,即使状态保存在服务器上(默认情况下)。这就要求视图范围的支持bean是可序列化的

这种方法的优点是历史就是真正的历史。当您返回到以前的视图版本(使用后退按钮)时,您实际上得到了当时支持bean的确切版本

缺点是它似乎破坏了服务的注入(与此问题无关,是对性能的重大打击)。注入EJB服务时也会出现同样的问题

您可以将一个上下文参数放入web.xml中以禁用此行为:


org.apache.myfaces.SERIALIZE_STATE_IN_SESSION
假的


顺便说一句,Mojarra有一个类似的设置,但默认值为false。

我在上发布了一个解决此问题的方法,它是这样的:不是通过EL在
@ManagedProperty
注释(在ManagedBean初始化时执行)中注入Spring bean,而是在运行时获得评估EL的bean

使用这种方法,您的JSF bean应该如下所示:

@ManagedBean(name="demandesBean")
@ViewScoped
public class DemandesBean implements Serializable {
    private static final long serialVersionUID = 1L;

    private static DemandeService demandeService() {
        return SpringJSFUtil.getBean("demandeService");
    }

    // ... 
    public void doAjouterDemande(ActionListener event) {
        demandeService().createDemande(newDemande, loginBean.getUsername());
        newDemande = new DemandeVO();
    }
    // ...
这里是使用的实用程序类SpringJSFUtil.java:

import javax.faces.context.FacesContext;
公共类SpringJSFUtil{
公共静态T getBean(字符串beanName){
if(beanName==null){
返回null;
}
返回getValue(“#{”+beanName+“}”);
}
@抑制警告(“未选中”)
私有静态T getValue(字符串表达式){
FacesContext context=FacesContext.getCurrentInstance();
return(T)context.getApplication().evaluateExpressionGet(上下文,
表达式、对象、类);
}
}

这就消除了SpringBean属性(以多做一些EL计算为代价),从而避免了将该属性放在首位的序列化问题。

ViewScoped bean中的所有内容都存储在ViewState中。您可以在会话中关闭ViewState序列化,但会话本身可以序列化,然后问题将在其他位置出现

Spring的解决方案是使用可序列化代理

<aop:scoped-proxy proxy-target-class="true"/>
回答,只是你不需要为每个bean自己编写代码。您可以使用aop

<aop:scoped-proxy proxy-target-class="true"/>

你可以看到我的问题:更多内容。

非常类似的问题,有解决方案,如下所示:
<aop:scoped-proxy proxy-target-class="true"/>