2011-01-04 3 views
1

JSFがいくつかのコンポーネントツリーを直列化することを明示的に拒否できますか?現時点では私は<h:inputText>に非直列化可能なオブジェクトを渡しています:アプリケーションの特定の部分に対するコンポーネントツリーの直列化の防止

<h:inputText value="#{nonSerializableBean.nonSerializableClassInstance}" /> 

数回のクリックは、私が(ビューの復元中に)取得することで後に何が起こる:

javax.faces.FacesException: Unexpected error restoring state for component 
with id configurationForm:j_idt292:j_idt302:field. Cause: 
java.lang.IllegalStateException: java.lang.InstantiationException: 
my.namespace.NonSerializableClass 

私はこれがために発生考えます

Caused by: java.lang.IllegalStateException: java.lang.InstantiationException: com.foobar.utils.text.Period 
at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:110) 
at javax.faces.component.ComponentStateHelper.restoreState(ComponentStateHelper.java:292) 
at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1444) 
at javax.faces.component.UIOutput.restoreState(UIOutput.java:255) 
at javax.faces.component.UIInput.restoreState(UIInput.java:1359) 

ボーナス質問::バッキングBeanはSerializableを作るためではない、それはOKですJSFはnonSerializableClassInstanceを復元することはできませんか?これは、これらのシリアル化/逆シリアル化を防止する必要がありますか?

いくつかの背景:

私たちは、JSFでのフォームを提供する必要があるサードパーティのクラスの束を持っています。問題は、これらのクラスをJSFページで直接使用することができない点です。これは、Serializableインターフェイスを実装していないため、JSFランタイムがページとコンポーネントツリーを直列化/逆シリアル化する場合に失敗するためです。クラスは「閉鎖」されており、変更することはできません。

Mojarra 2.0.2を実行しています。

+1

* *ページと*これらのクラスはどういう意味ですか? JSFのページをシリアライズ可能と宣言する方法がわかりません。あなたはもう少し明確にすることができますか?いくつかのコードサンプルを提供することによって? –

+0

申し訳ありませんが、私はバッキング豆を意味します。あなたはJSFに*ページ*がないことは間違いありません(ただし、ViewRootがあります)。私はここで私の考えに問題がある、私は問題をよりよく反映するために質問を更新する。 –

答えて

4

Javabeans specSerializableが実装されています。 JSFはこの仕様に従うだけです。

クラスは「閉鎖」されており、変更することはできません。

あなたの最善の策はSerializableを実装するクラスのtransientプロパティとしてそれをラップし、それに応じてwriteObject()readObject()を実装することです。

public class SerializableClass implements Serializable { 

    private transient NonSerializableClass nonSerializableClass; 

    public SerializableClass(NonSerializableClass nonSerializableClass) { 
     this.nonSerializableClass = nonSerializableClass; 
    } 

    public NonSerializableClass getNonSerializableClass() { 
     return nonSerializableClass; 
    } 

    private void writeObject(ObjectOutputStream oos) throws IOException { 
     oos.defaultWriteObject(); 
     oos.writeObject(nonSerializableClass.getProperty1()); 
     oos.writeObject(nonSerializableClass.getProperty2()); 
     // ... 
    } 

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { 
     ois.defaultReadObject(); 
     nonSerializableClass = new NonSerializableClass(); 
     nonSerializableClass.setProperty1((String) ois.readObject()); 
     nonSerializableClass.setProperty2((String) ois.readObject()); 
     // ... 
    } 

} 

最後に、代わりにそのクラスを使用してください。最終的にはそれをextends NonSerializableClassにして、ちょうど良いIDEでデリゲートメソッドを自動生成することができます。

どちらの方法でも、不透明で定型的なコードが多くなりますが、これらのクラスを変更することはできません(個人的には、サードパーティのものをプッシュして、 Serializableを実装するためにJavabeansと呼ばれていました。なぜなら、誰が標準/仕様を破っているからですか)。

+0

これは実際に私がやったこととまったく同じです。ここに示したように、 'Serializable'ラッパークラスを作成し、カスタムセーブセーブ/リストアを行いました。問題は、深いオブジェクト階層(私たちがフォームを作成するデータを提示する)を持っていることです。これらの階層をトラバースし、各直列化できないクラスをラッパーなどにマッピングする必要があります。しかし、「ちょっとしたIDEでデリゲートメソッドを自動生成する」とはどういう意味ですか? –

+0

http://stackoverflow.com/questions/4546807/implementing-multiple-interfaces-with-java-is-there-a-way-to-delegate/4546871#4546871 – BalusC

+0

未来のために知っておくとよい機能です!一方、いくつかの問題のあるクラスとXMLスキーマのソースコードを取得していたので、 'Serializable'を実装して新しいJAXB変換を行いました。問題が解決しました。特定のプロパティのシリアル化を防ぐことはできません(そのため、それらを含む豆)。それが不可能な場合は、JSFコンポーネントにBeanに存在しないプロパティを渡すことは可能でしょうか?私はこれが、JSFが存続するすべての基盤との戦いだと思いますか? –

1

クラスメンバー(例:nonSerializableClassInstance)がシリアル化されていない場合は、私はあなたが期待するものがわかりません。 もちろん、それらをtransientとしてマークすることができます。

管理対象Beanの目的は、アプリケーションの状態を保持することです。一部のメンバーがシリアル化されていない場合(サーバーがこれを行う必要がある場合)、状態は失われます。

+0

私はそれらを一時的にマークすることができましたが、(Beanの状態復元で)それらを復元するには別の方法が必要でした。しかし、* JSF *は、シリアル化できないクラスインスタンスをフィールドに渡し(例えば 'h:inputText')、コンポーネントツリーを復元することができず、そこでカスタム処理を行う方法がわからないことを伝えています。また、これらはサードパーティーのクラスであり、シリアライズ可能にすることはできません。そのため、JSFがこれらのツリーをディスクに永続化させないようにするのが最も簡単な方法です。私はむしろメモリが最終的に使い果たされるならばエラーページにユーザーをリダイレクトしたい(私たちはたくさんのRAMを持っている...)。 –

関連する問題