9

こんにちは私はViewScopedBeanを使用しています。問題は、それを呼び出すと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

この問題の修正はありますか?助けてください !

4

3 に答える 3

7

もう 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 です。

于 2012-04-28T12:21:07.833 に答える
0

この同じ問題に関する自分の質問に、この問題の解決策を投稿しました。これは次のようになります。EL を介して Spring Bean を@ManagedPropertyアノテーション (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 評価をさらに数回実行するという代償を払って)、最初にプロパティを使用するというシリアライゼーションの問題が回避されます。

于 2012-07-16T20:42:52.460 に答える
0

ViewScoped Bean のすべてが ViewState に格納されます。セッションでViewStateのシリアル化をオフにすることはできますが、セッション自体をシリアル化すると、別の場所で問題が発生します。

Spring での解決策は、Serializable Proxyを使用することです。

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

Spring Bean はプロキシでラップされ、つまりシリアライズ可能であり、ラップされた参照は一時的であるため、デシリアライズ後にスプリング コンテキストから再読み取りされます。

技術的にはエリアスの回答に似ていますが、Beanごとにそのコードを自分で書く必要がないだけです。aopを利用します。

私の質問を見ることができます: JSF Beans and serializability issue for more context.

于 2013-01-30T08:03:33.630 に答える