2017-04-02 71 views
0

在我的應用程序中有一個對象樹。爲了構成該樹,每個對象都有一個父引用。由於某些對象類型可以是幾個父對象類型的子對象,因此所有可能的父對象類型都通過實現一個通用接口來統一。 我縮小了問題(JAXB抱怨父成員變量(標@XmlIDREF和@XmlAttribute)作爲一個接口),就像我可以:SomeObject是一個接口,JAXB不能處理接口

public interface Parent{ 
    @XmlID 
    @XmlAttribute(name = "oid") 
    public String getID(); 
    public void setID(String id); 
} 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.NONE) 
public class ChildObject implements Parent{ 
    @XmlTransient 
    private UUID id = UUID.randomUUID(); 

    @XmlIDREF 
    @XmlAttribute 
    protected Parent parent = null; 

    public ChildObject() {} 

    public ChildObject(Parent parent){ 
     this.parent = parent; 
    } 

    @XmlID 
    @XmlAttribute 
    @Override 
    public String getID(){ return(id.toString()); } 

    @Override 
    public void setID(String id){ this.id = UUID.fromString(id); } 
} 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.NONE) 
public class Repository{ 

    @XmlElement 
    private List<ChildObject> objects = new ArrayList<>(); 

    public Repository() {} 

    public ChildObject addObject(ChildObject o){ 
     objects.add(o); 
     return(o); 
    } 

    public static void main(String[] args){ 
     Repository r = new Repository(); 
     ChildObject root = r.addObject(new ChildObject()); 
     ChildObject c0 = r.addObject(new ChildObject(root)); 
     ChildObject c1 = r.addObject(new ChildObject(root)); 
     ChildObject c11 = r.addObject(new ChildObject(c1)); 
     ChildObject c12 = r.addObject(new ChildObject(c1)); 
     try{ 
      JAXBContext context = JAXBContext.newInstance(Repository.class); 
      Marshaller marshaller = context.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(r, System.out); 
     }catch(Exception ex){ ex.printStackTrace(); } 
    } 
} 

這是試圖運行時異常我得到的,它:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException:IllegalAnnotationExceptions家長1個 計數是一個接口,而JAXB 不能處理接口。在 庫

在 com.sun.xml.internal.bind處受保護的家長ChildObject.parent家長在 ChildObject在私人的java.util.List Repository.objects:這個問題涉及到以下 位置。 v2.runtime.IllegalAnnotationsException $ Builder.check(IllegalAnnotationsException.java:91) 在 com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445) 在 的com.sun。 xml.internal.bind.v2.runtime.JAXBContextImpl。(JAXBContextImpl.java:277) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl。(JAXBContextImpl.jav a:124) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl $ JAXBContextBuilder.build(JAXBContextImpl.java:1123) at com.sun.xml.internal.bind.v2.ContextFactory。的createContext(ContextFactory.java:147) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl。的java:43) 在java.lang.reflect.Method.invoke(Method.java:498)處 javax.xml.bind.ContextFinder javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)。 newInstance(ContextFinder.java:234)javax.xml.bind.JAXBContext.newInstance(JAXBContext.java)(150) :584)在 Repository.main(Repository.java:33)

這是JAXB的預期行爲(或者是一個bug)和我應該做的就是圍繞它是什麼?

回答

1

我加上空@XmlJavaTypeAdapter的接口,像這樣解決了這個問題:

@XmlAccessorType(XmlAccessType.NONE) 
@XmlJavaTypeAdapter(ChildObject.ParentAdapter.class) 
public interface Parent{ 
    @XmlID 
    @XmlAttribute(name = "oid") 
    public abstract String getID(); 
    public abstract void setID(String id); 
} 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.NONE) 
public class ChildObject implements Parent{ 

    @XmlTransient 
    private UUID id = UUID.randomUUID(); 

    @XmlIDREF 
    @XmlAttribute 
    protected Parent parent = null; 

    public ChildObject() {} 

    public ChildObject(Parent parent){ 
     this.parent = parent; 
    } 

    @XmlID 
    @XmlAttribute(name = "oid") 
    @Override 
    public String getID(){ return(id.toString()); } 

    @Override 
    public void setID(String id){ this.id = UUID.fromString(id); } 


    public static class ParentAdapter extends XmlAdapter<Object,Object>{ 
     @Override 
     public Object marshal(Object arg0) throws Exception{ return arg0; } 

     @Override 
     public Object unmarshal(Object arg0) throws Exception{ return arg0; } 
    } 
} 

不過,我不知道這是否是一個錯誤或JAXB(甲骨文JDK 8u121)的預期行爲

+1

用'@ XmlTransient'註解接口也可以。不需要空的'XmlAdapter' – toKrause

相關問題