2011-12-23 6 views
1

XMLEncoderに次の問題があります。私はこのようになりますクラスをシリアル化したい:XMLシリアル化のみ1つのフィールドをシリアル化

public class MyClass{ 
    private Object myObject; 
    private Object anotherObject; 
    private static MyClass instance = new MyClass(); 

    [myObject and anotherObject are set in the class later...] 

    public static MyClass getInstance(){ 
     return instance; 
    } 

    [getter and setter methods here] 
} 

今、私はこの(MyClassの内側)のようなオブジェクトシリアライズしたい:

public void saveObject(){ 
     [try catch stuff not shown] 
     FileOutputStream fos = new FileOutputStream(new File("object.xml")); 
    XMLEncoder xmle = new XMLEncoder(fos); 
    xmle.writeObject(instance); 
    xmle.close(); 
} 

をしかし、私のobject.xmlは、の値が含まれていませんmyObjectとanotherInstanceは次のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_24" class="java.beans.XMLDecoder"> 
<object class="MyClass"/> 
</java> 

What's going on? XMLEncoderは、同じクラスの静的フィールドを持つループを検出し、それをさらに直列化しませんか?しかし、私はエラーが発生しません... 私はシリアル化できないか、何か他のものとしてそのフィールドをマークできますか?

答えて

1

任意のクラス(JavaBeans規約に準拠していないクラス)でXmlEncoderを使用したい場合は、こちらを参考にしてください。

Advanced use of XmlEncoder

EDIT:あなたの助けになるかもしれないそこに少し宣伝文句があります。

XMLEncoderは、オブジェクトグラフを複製し、クローンの作成に必要な手順を記録します。このようにして、XMLEncoderはXMLDecoderがファイルをデコードするために必要なステップを模倣するオブジェクトグラフの「作業コピー」を持っています。この作業コピーの状態を監視することにより、エンコーダーはプロパティー値をデフォルト値に設定する操作を省略でき、冗長な情報をほとんど必要としない簡潔な文書を作成できます。

myObjectanotherObjectの値は代わりにデフォルトとして初期化されるのinstance変数に設定されている場合に予想されるように、あなたの例では、すべてが動作します。

public void saveObject(){ 
     [try catch stuff not shown] 
     instance.setObject(new Object()); 
     FileOutputStream fos = new FileOutputStream(new File("object.xml")); 
    XMLEncoder xmle = new XMLEncoder(fos); 
    xmle.writeObject(instance); 
    xmle.close(); 
} 
+0

私はXMLEncoderを初めて使用しましたが、あなたの説明どおりに動作しました...しかし、この場合は動作しません!たとえ私がすべてのinitのものをコンストラクタの中に入れたとしても... – reox

2

XMLEncoderは、 'Java Beans'をエンコードします。フィールドの認識はありません。 getterとsetterのみを使用します。 「ループ」があった場合は、xml:idxml:idrefを使用して参照を処理します。

+0

はい私はゲッターとセッターを持っていますが、方法は何とか使われていませんか? – reox

+1

@reoxあなたがしたコードではなく、OPには含まれていないコードをデバッグするようにお願いしていますか? –

1

XMLEncoderはJavaBeansで動作するように設計されています。これは、直列化ツリー内のすべてのオブジェクトがなければならないことを意味します

  • はゲッターとあなたがシリアライズしたい各プロパティのセッターを持っている公共デフォルト(つまり、引数なし)コンストラクタ

  • を持っている(Aシリアライゼーションのためのゲッターとデシリアライゼーションのためのセッター)。サイドノートとして

あなたはゲッター/セッターを維持するが、が属性をシリアル化したくない場合は、物事は、イントロスペクションの使用と少し複雑になります:

// let's get the BeanInfo of class MyClass 
BeanInfo info = Introspector.getBeanInfo(MyClass.class); 

// we'll work with PropertyDescriptors to prevent the bar attribute from being serialized 
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors(); 
for (PropertyDescriptor descriptor : propertyDescriptors) { 
    if (descriptor.getName().equals("bar")) { 
     //the correct PropertyDescriptor is set to transient. 
     //Note that you actually have to do this via the BeanInfo/PropertyDescriptor for it to work 
     descriptor.setValue("transient", Boolean.TRUE); 
    } 
} 
+0

合意。特に一般的な問題は、メンバーとして、パブリックデフォルト(引数なし)コンストラクターを持たないオブジェクトBを含むオブジェクトAをエンコードしようとするときです。その場合、Bはエンコードされたバージョンには表示されません。 – hrabinowitz