【问题标题】:ViewScoped Bean cause NotSerializableExceptionViewScoped Bean 导致 NotSerializableException
【发布时间】:2011-04-20 13:49:29
【问题描述】:

您好,我使用的是 ViewScoped 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;
    }
}

我收到以下异常:

GRAVE: Exiting serializeView - Could not serialize state: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl
java.io.NotSerializableException: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl

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

【问题讨论】:

标签: spring jsf serialization jsf-2 notserializableexception


【解决方案1】:

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

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

缺点是它似乎破坏了服务注入(与此问题无关,是主要的性能损失)。注入 EJB 服务时也会出现完全相同的问题。

您可以在 web.xml 中添加一个上下文参数来禁用此行为:

<context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
</context-param>

http://wiki.apache.org/myfaces/Performance

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

【讨论】:

    【解决方案2】:

    我在my own question about this same problem 上发布了针对此问题的解决方案,如下所示:不是通过@ManagedProperty 注释中的EL 注入Spring bean(在ManagedBean 初始化时执行),而是在以下位置获得评估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;
    
    public class SpringJSFUtil {
    
        public static <T> T getBean(String beanName) {
            if (beanName == null) {
                return null;
            }
            return getValue("#{" + beanName + "}");
        }
    
        @SuppressWarnings("unchecked")
        private static <T> T getValue(String expression) {
            FacesContext context = FacesContext.getCurrentInstance();
            return (T) context.getApplication().evaluateExpressionGet(context,
                    expression, Object.class);
        }
    }
    

    这消除了 Spring bean 属性(以多做几次 EL 评估为代价),从而避免了将属性放在首位的序列化问题。

    【讨论】:

      【解决方案3】:

      ViewScoped bean 中的所有内容都存储在 ViewState 中。你可以在 session 中关闭 ViewState 序列化,但是 session 本身可以被序列化,然后问题会出现在其他地方。

      Spring 的解决方案是使用 Serializable Proxy

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

      Spring bean 被包裹在代理中,即可序列化,并且被包裹的引用是瞬态的,所以反序列化后会从 Spring 上下文中重新读取。

      它在技术上类似于elias 答案,只是您不需要为每个 bean 自己编写该代码。您使用 aop

      您可以查看我的问题:JSF beans and serializability issue 了解更多上下文。

      【讨论】:

        猜你喜欢
        • 2011-03-03
        • 2012-10-17
        • 2011-02-20
        • 2011-12-07
        • 1970-01-01
        • 2015-04-15
        • 1970-01-01
        • 2013-11-20
        • 2012-10-15
        相关资源
        最近更新 更多