1

JAXB xml にマーシャリングしようとしている既存の複雑なオブジェクト モデルがあります。可能であれば、既存のドメイン クラスを変更したくありません。ファイルにマーシャリングするためにこのスニペットが機能しています(Groovyを使用)

def marshallToFile(Object objectToMarshall, File location){

    def context = JAXBContext.newInstance(objectToMarshall.class)

    def m = context.createMarshaller()
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true)

    location.withOutputStream { out ->
        m.marshal(new JAXBElement(new QName("","rootTag"),objectToMarshall.class,objectToMarshall), out)
    }

}

問題は、オブジェクト グラフが非常に複雑であり、JAXB が教えてくれることです。com.sun.istack.internal.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: com.example.Object@1eef1eb[Id=100053900] -> com.example.Object@1eef1eb[Id=100053900]

検出されたサイクルに関する詳細情報を取得する方法はありますか? サイクルを選択できるように、グラフを分析したり、グラフィカルにリストしたりするのに役立つツールを知っている人はいますか? このグラフには多くのサイクルがあると感じています(古くて複雑です)ので、助けていただければ幸いです。

別の方法として、無限に深い XML を作成しないように、JAXB に 'n' レベルまたは類似のレベルのみを設定するように指示できますか?

編集:

したがって、私の特定の問題に関して...既存のドメインオブジェクトには、自己参照キーワードを「取得」Object getThis()およびvoid setThis(Object obj)「設定」するメソッドが定義されていることがわかりました。thisそれが私のサイクルの原因でした。これは、JAXB がどのプロパティをマーシャリングするかを決定するために JavaBean メソッド定義を使用する必要があるという事実も浮き彫りにします (私はこれまで知りませんでした)。

ただし、元の質問はまだ残っていると思います。オブジェクト グラフを分析/表示するための優れたツールはありますか?

4

2 に答える 2

2

おそらく、Marshaller.Listenerを導入して、診断の目的で、マーシャリングプロセスをトレースし、オブジェクト情報をダンプすることができます。詳細については、「マーシャルイベントコールバック」(「外部リスナー」を参照する部分)を参照してください。これには、既存のドメインへの変更は必要ありません。

于 2013-01-11T15:33:10.927 に答える
0

CycleRecoverableサイクルに関する情報を見つけるために、オブジェクトにインターフェイスを実装させることができます。

import java.util.*;
import javax.xml.bind.annotation.*;
import com.sun.xml.bind.CycleRecoverable;

@XmlRootElement
public class Department implements CycleRecoverable {

   @XmlAttribute
   public int id;
   public String name;
   public List<Employee> employees = new ArrayList<Employee>();

   public Object onCycleDetected(Context arg0) {
       // Context provides access to the Marshaller being used:
       System.out.println("JAXB Marshaller is: " + cycleRecoveryContext.getMarshaller());

       DepartmentPointer p = new DepartmentPointer();
       p.id = this.id;
       return p;
   }

}

詳細については

于 2013-01-11T15:25:56.707 に答える