有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从JAXBContext中未使用的对象链接XmlElements?

在创建Marsaller时,是否有任何方法可以链接或引用JAXBContext中未使用的类中的XmlElements

我正在使用Jersey将JAXB注释对象转换为XML文件

这是我的设置。所有类都在同一个包中

对于Marsaller,我使用B、C或D类

@XmlAccessorType(XmlAccessType.NONE)
class A {
    private Foo foo;

    public SomeObject getSomeObjetct() {
        return foo.getSomeObjetct();
    }


    protected setFooBehavior(Foo f) {
        this.foo = f;
    }



    /* From this point the XmlElements are commond to all subclasses
     * and no other special manipulation take place.
     */  

    @XmlElement(...)
    ...someGetterMethod(){}

    @XmlElement(...)
    ...someOtherGetterMethod(){}

    @XmlElement(...)
    ...someThirdGetterMethod(){}

    ...
    ...


}

@XmlRootElement(name = "B")
class B extends A{
    setFooBehavior(new FooA());
}

@XmlRootElement(name = "C")
class C extends A{
    setFooBehavior(new FooA());
}

@XmlRootElement(name = "D")
class D extends A{
    setFooBehavior(new FooB());
}

class FooA {
    SomeObject someObject;

    @XmlElement(name = "FooA", required = true)
    public SomeObject getSomeObjetct() {
        return getSomeObjetct();
    }

    public setSomeObject(SomeObject someObject;) {
        this.someObject = SomeObject someObject;;
    }
}

class FooB {
    SomeObject someObject;

    @XmlElement(name = "FooB", required = true)
    public SomeObject getSomeObjetct() {
        return getSomeObjetct();
    }

    public setSomeObject(SomeObject someObject;) {
        this.someObject = SomeObject someObject;;
    }
}

每种情况下的Marsaller都是

JAXBContext jaxbContext = JAXBContext.newInstance(C.class); //or B.class or D.class
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

最后,我希望得到以下xml结果

C类

<C>
    <FooA>someObjectValue</FooA>
</C>

D班呢

<D>
    <FooB>someObjectValue</FooB>
</D>

我现在得到的输出是

<C>
    <someObject>someObjectValue</someObject>
<C>

<D>
    <someObject>someObjectValue</someObject>
</D>

分别


共 (1) 个答案

  1. # 1 楼答案

    您提到了D中的someObject需要特殊处理。您仍然有一个Foo实例吗?你能做到:

    public class A {
    
        @XmlElementRef
        public Foo getFoo() {
            return foo;
        }
    
        @XmlTransient
        public SomeObject getSomeObject() {
            return foo.getSomeObject();
        }
    
    }
    

    更新:如果您不能公开Foo,那么信息必须存储在其他机制中。以下解决方案不是很好,但可能有用:

    public class A {
    
        private Class<?> fooType;
    
        //protected should be enough for JAX-B and will
        //hide the method from the rest of your code.
        @XmlAnyElement
        protected JAXBElement<SomeObject> getSomeObjetctForJaxb() {
            return new JAXBElement<SomeObject>(new QName(fooType.getSimpleName()), SomeObject.class, getSomeObjetct());
        }
    
    }
    

    您还需要解组XML吗?如果是这样,您将需要一个setter,它接受一个JAXBElement<SomeObject>,并且必须根据元素的名称适当地创建Foo