我有一个现有的复杂对象模型,我试图编组到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]
有没有办法获得有关检测周期的更多信息?有没有人知道有助于分析图形或以图形方式列出图表的工具,以便我可以选出周期?我觉得这个图表中有很多周期(它是旧的和复杂的)所以任何帮助都会受到赞赏。
也许作为替代方案,你能告诉JAXB只是深入或类似的东西,所以它不会创建无限深度的XML吗?
修改
关于我的具体问题......结果是现有的域对象定义了Object getThis()
和void setThis(Object obj)
方法,即“获取”和“设置”this
自我-reference关键字。这就是导致我的周期的原因。这也突出了这样一个事实,即JAXB必须使用JavaBean方法定义来确定它将要编组的属性(我之前不知道)。
但是,我认为最初的问题仍然存在,是否有用于分析/查看对象图的好工具?
答案 0 :(得分:2)
也许您可以引入Marshaller.Listener来跟踪编组过程并转储对象信息,以便进行诊断。有关详细信息,请参阅"Marshal Event Callbacks"(引用“外部侦听器”的部分)。这不应该要求更改现有域。
答案 1 :(得分: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;
}
}
了解更多信息