java - SomeObject是一个接口(interface),JAXB不能处理接口(interface)

标签 java jaxb

在我的应用程序中有一棵对象树。为了构成这棵树,每个对象都有一个父引用。由于某些对象类型可以是多个父对象类型的子对象,所有潜在的父对象类型都通过实现一个公共(public)接口(interface)来统一。 我尽可能地缩小了问题范围(JAXB 提示父成员变量(注释为@XmlIDREF 和@XmlAttribute)是一个接口(interface)):

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: 1 counts of IllegalAnnotationExceptions Parent is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at Parent at protected Parent ChildObject.parent at ChildObject at private java.util.List Repository.objects at Repository

at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:277) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java: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) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234) at javax.xml.bind.ContextFinder.find(ContextFinder.java:462) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584) at Repository.main(Repository.java:33)

这是 JAXB 的预期行为吗(或者这是一个错误),我应该怎么做才能绕过它?

最佳答案

我通过向接口(interface)添加一个虚拟 @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 (Oracle JDK 8u121) 的预期行为

关于java - SomeObject是一个接口(interface),JAXB不能处理接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43167095/

相关文章:

java - Java 序列化、JSON、JAXB 之间的区别?

Java RMI 应用程序不退出

java - 无法使用 xjc 编译器和绑定(bind)文件从 wsdl 文件生成顶级 JAXB

java - JSON 解析错误 : Can not deserialize instance of java. util.ArrayList 超出 START_OBJECT token

java - Struts 1.2 intRange 验证失败

java - JAXB 接受重复标签

xml - jackson 在序列化为 JSON 时无法考虑 @XmlElement

java - 如何解码 FaultMessageResolver 中的 SOAP 错误?

java - JPA/Hibernate 中的单独表与额外列

Java map 同步