3

複雑なXMLドキュメントを解析する必要があります。私のモデルのいくつかのクラスはインターフェースを実装していますHasDate

interface HasDate {
    public void setDate(Date date);
}

unmarshallerが作成された日付は次のとおりです。

// here I know the date.
JAXBContext ctx = JAXBContext.newInstance("com.mycompany.mymodel");
Unmarshaller unmarshaller = ctx.createUnmarshaller();
unmarshaller.unmarshal(input);

JAXBがドキュメントを解析している間setDate()に実装するクラスの各インスタンスを呼び出したいと思います。HasDate

これが私が知っている2つの解決策です:私は次のように関連する各クラスに注釈を付けることができます:

@XmlType(factoryClass = ObjectFactory.class, factoryMethod = "createMyObject")

メソッドcreateMyObject()はを呼び出しますsetDate()。このソリューションの問題は、createMyObject()静的でなければならないということです。情報を静的メンバーとして設定すると、ソリューションはスレッドセーフではなくなります。

このソリューションの変形として、ThreadLocal解析の直前に日付を設定できます。createMyObject()から日付を読み取り、 ThreadLocalを呼び出しますsetDate()。このソリューションはスレッドセーフですが、パッチのように見えます。

他の解決策は、リフレクションを使用してJAXBによって作成されたオブジェクトグラフを検出し、それを再帰的にトラバースしsetDate()、必要に応じて呼び出すことです。このソリューションはスレッドセーフですが、実装作業が必要であり、将来的にはメンテナンスが必要です。

JAXBには、この問題に対する他の組み込みソリューションがあるのではないかと思います。

4

2 に答える 2

2

@XmlAdapterインターフェイスを実装するすべてのクラスに使用することをお勧めしHasDateます。これにより、ユースケースが明示的でタイプセーフになります。ThreadLocalから日付を検索することを理解するベースアダプターを持つことができます。

XmlAdapter:JAXBの秘密兵器

このオプションが機能しない場合は、afterUnmarshallライフサイクルメソッドで呼び出されるリフレクションアプローチが好きです。

于 2012-08-23T17:29:54.347 に答える
2

を実装してUnmarshaller.Listener、に設定できますUnmarshaller。次にafterUnmarshal、ターゲットクラスがのインスタンスである場合HasDate、メソッドでメソッドを呼び出すことができますsetDate

于 2012-08-23T17:52:25.220 に答える