使用 @XmlIDREF 避免 JAXB 循环引用
我在 Web 服务中使用 JAXB 和一些稍微复杂的对象。其中一个对象 Sensor 有一个可以与之通信的其他对象的列表,这些对象必然可以包含其自身(无法更改的行为),从而导致在编组到 XML 期间出现循环引用。
@XmlAccessorType(XmlAccessType.FIELD)
public class Sensor extends BaseObject {
private ArrayList<SensorCommLink> sensorCommLinks;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class SensorCommLink {
@XmlIDREF
private BaseObject receiver;
@XmlIDREF
private Sensor cueingSensor;
}
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class BaseObject {
@XmlElement
@XmlID
private String id;
}
如上所示,我使用 @XmlIDREF 和 @XmlID 解决了这个问题,并且效果非常好。
通过 wsimport 生成的客户端代码将对象编组为 XML,并且服务器能够完美地解组它们。
我遇到的问题是,由于某种原因,当我尝试封送传感器对象时,在服务器端出现循环引用异常。令人抓狂的部分是,服务器端代码包含 wsimport 用于创建客户端代码的 JAXB 注释,效果很好,但由于循环原因,我无法编组服务器端传感器。
我尝试将 JAXB 添加到客户端代码的所有额外注释复制到服务器端类上,认为 JAXB 中可能存在运行时错误,导致它无法正确应用 @XmlIDREF 注释。那里没有运气。
也许我在这里遗漏了一些非常基本的东西,但这个问题让我有点抓狂,当我试图弄清楚它时,我陷入了僵局。
我确实注意到我正在调查的一件事是,生成的客户端对象上的一些名称空间不是我所期望的,尽管代码可以工作。我很好奇服务器上的名称空间问题是否会导致 IDREF 编组崩溃。
I'm using JAXB in a web service with some slightly complex objects. One of the objects, Sensor, has a list of other objects it can communicate with, which necessarily can include itself (behavior that cannot be changed), leading to a cyclic reference during marshalling to XML.
@XmlAccessorType(XmlAccessType.FIELD)
public class Sensor extends BaseObject {
private ArrayList<SensorCommLink> sensorCommLinks;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class SensorCommLink {
@XmlIDREF
private BaseObject receiver;
@XmlIDREF
private Sensor cueingSensor;
}
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class BaseObject {
@XmlElement
@XmlID
private String id;
}
As shown above I solved this using @XmlIDREF and @XmlID and it works very nicely.
The client-side code generated via wsimport marshals the objects to XML and the server is able to unmarshal them perfectly.
The problem I'm experiencing is that for some reason on the server side I am getting a cyclic reference exception when I try to marshal a Sensor object. The maddening part is that the server-side code contains the JAXB annotations that are used by wsimport to create the client-side code, which works great, yet I can't marshal server-side Sensors due to the cycle.
I tried copying all of the extra annotations JAXB adds to the client-side code onto the server-side classes thinking perhaps there was a runtime bug in JAXB that was preventing it from properly applying the @XmlIDREF annotation. No luck there.
Perhaps there's something very basic I'm missing here but this issue is driving me a little batty and I'm at a dead stop while I try to figure it out.
One thing I did notice that I'm investigating is that some of the namespaces on the generated client-side objects aren't what I expected, though the code works. I'm curious to see if somehow a namespace issue on the server is causing the IDREF marshalling to bomb.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在服务器端,它有可能处理属性(获取/设置)而不是字段(实例变量)。您可以通过以下方式强制执行字段访问:
@XmlAccessorType(XmlAccessType.FIELD)
public class SensorCommLink {
}
或者您可以注释 get 方法。
Any chance on the server side it is processing properties (get/set) instead of fields (instance variables). You can enforce field access in the following way:
@XmlAccessorType(XmlAccessType.FIELD)
public class SensorCommLink {
}
Or you could annotate the get methods.