首先是一个小例子。类ReferencingEntity包含对抽象类AbstractEntity的引用。这个类有两种实现方式:
@XmlRootElement
public abstract class AbstractEntity {
@XmlID
private String id;
}
@XmlRootElement
public class EntityImpl1 extends AbstractEntity {
}
@XmlRootElement
public class EntityImpl2 extends AbstractEntity {
}
@XmlRootElement
public class ReferencingEntity {
@XmlIDREF
private AbstractEntity entity;
}
编组ReferencingEntity实例没有问题(除了xml中没有具体类型),但是当尝试解组xml表示时,缺少描述符来确定具体实现。
目前我正在使用XmlAdapter将所有非id字段设置为null,但如果可能,最好使用@XmlID。有什么想法吗?
更新: 我在JBoss 6.1.0.Final中使用RESTEasy,提供程序创建上下文:
ContextResolver<JAXBContextFinder> resolver = providers.getContextResolver(JAXBContextFinder.class, mediaType);
JAXBContextFinder finder = resolver.getContext(type);
if (finder == null)
{
if (reader) throw new JAXBUnmarshalException("Could not find JAXBContextFinder for media type: " + mediaType);
else throw new JAXBMarshalException("Could not find JAXBContextFinder for media type: " + mediaType);
}
JAXBContext context = finder.findCachedContext(type, mediaType, annotations);
答案 0 :(得分:1)
以下是我对你问题的初步回答。我想它会随着我更好地理解你的用例而发展。
关于@XmlID
/ @XmlIDREF
从带有@XmlIDREF
注释的字段/属性引用的每个实例也需要通过包含引用。我将在本例中使用下面的类。
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Root {
private AbstractEntity abstractEntity;
private ReferencingEntity referencingEntity;
public AbstractEntity getAbstractEntity() {
return abstractEntity;
}
public void setAbstractEntity(AbstractEntity abstractEntity) {
this.abstractEntity = abstractEntity;
}
public ReferencingEntity getReferencingEntity() {
return referencingEntity;
}
public void setReferencingEntity(ReferencingEntity referencingEntity) {
this.referencingEntity = referencingEntity;
}
}
关于遗传
JAXB(JSR-222)实现无法自动发现子类,因此您需要确保JAXBContext
知道它们。实现此目的的一种方法是使用父类的@XmlSeeAlso
注释指向子类。
import javax.xml.bind.annotation.*;
@XmlSeeAlso({EntityImpl1.class, EntityImpl2.class})
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractEntity {
@XmlID
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
DEMO CODE
<强>演示强>
package forum12111815;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum12111815/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
System.out.println(root.getAbstractEntity().getClass());
System.out.println(root.getAbstractEntity() == root.getReferencingEntity().getEntity());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
的 input.xml中强> 的
<?xml version="1.0" encoding="UTF-8"?>
<root>
<abstractEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="entityImpl2">
<id>123</id>
</abstractEntity>
<referencingEntity>
<entity>123</entity>
</referencingEntity>
</root>
的输出强> 的
class forum12111815.EntityImpl2
true
<?xml version="1.0" encoding="UTF-8"?>
<root>
<abstractEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="entityImpl2">
<id>123</id>
</abstractEntity>
<referencingEntity>
<entity>123</entity>
</referencingEntity>
</root>
更多信息