2012-08-24 33 views
1

首先是一個小例子。 ReferencingEntity類保存對抽象類AbstractEntity的引用。有兩種實現FO此類:使用XmlIDRef參考抽象類

@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

你是如何創建'JAXBContext'? –

+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> 

瞭解更多信息

+0

啊,不明白@XmlIDRef的用途。但是當我考慮它時,這是有道理的,因爲如果沒有包含被引用實體的xml,解編ID引用將是不可能的。感謝您及時的回覆。 –