2017-04-02 82 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

相关问题