1

首先是一个小例子。类 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;
}

编组引用实体的实例没有问题(除了具体类型不存在于 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);
4

1 回答 1

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;
    }

}

演示代码

演示

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);
    }

}

输入.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>

了解更多信息

于 2012-08-24T15:37:52.217 回答