9

コンバーターを作成する方法や、すべての変換後に実行される操作はありますか? コンテキストとして、データ モデルが変更された場合に後方互換性を維持するために、XML にないフィールドのデフォルト値を入力しようとしています。たとえば、次のオブジェクトがあるとします。

class A {
    private String b;
    private String c;
    private String d;
}

私のXMLは次のようなものでした:

<a>
 <b>b</b>
 <d>d</d>
</a>

XML のインポートで、フィールドにデフォルト値があることを認識し、そのようにc設定"c"したいと考えていますA。これは、非常に複雑なグラフの任意のフィールドにデフォルトを追加できる一般的な操作である必要があります。変換のたびに関数をトリガーする方法があれば、デフォルト値を設定したいオブジェクトのマップに対して現在のオブジェクトをチェックできます。

また、readResolve/readObject の使用は、1. readObject() がまったく機能しないように見え、2. readResolve が実際に XML に含まれている場合でもフィールドをデフォルト値で上書きするため、オプションではないように見えることに注意してください。 . ここでの私の仮定が間違っている場合はお知らせください。

編集:: ユーザーメーリングリストでこの関連スレッドを見つけました: http://article.gmane.org/gmane.comp.java.xstream.user/4619/match=default+value

唯一の提案された解決策はreadResolve()、有効な解決策ではないと既に述べた使用することです。

4

3 に答える 3

12

PureJavaReflectionProviderを使用する

XStream xstream = new XStream(new PureJavaReflectionProvider());

通常どおりデフォルト値でオブジェクトを初期化するだけです。フィールドの初期化またはコンストラクター コード (イニシャライザー) のいずれかを使用します。

バックグラウンド

指定しない場合、ReflectionProviderxstream は最適なリフレクション プロバイダーを見つけようとします。ただし、ReflectionProvider通常はSun14ReflectionProvider.

Sun14ReflectionProvider、Java シリアライゼーション メカニズムと同じインスタンス化戦略を使用します。つまり、コンストラクター コード、より正確には、オブジェクト初期化コードをスキップします。

したがって、次のようなインスタンス フィールドの初期化

class A {
    private String b = "DEFAULT";
}

適用されず、コンストラクターコードも適用されません。

class A {
    private String b;

    public A(){
        b = "DEFAULT";
    }
}

PureJavaReflectionProvider代わりに、(名前が示すように) Java リフレクション API を使用してオブジェクトをインスタンス化します。たとえば 、Class.newInstance()オブジェクトの初期化コードが実行されます。

于 2015-04-20T12:19:54.720 に答える