Jaxb基类的附加包装器



我有一个子类派生自基类父类。我想在基类的属性周围添加一个包装器。

Parent.java

package test;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Parent {
    int a;
    int b;
    String name;
    public Parent() {
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Child.java

package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Child extends Parent {
    private String foo;
    public Child() {
    }
    public String getFoo() {
        return foo;
    }
    public void setFoo(String foo) {
        this.foo = foo;
    }
}

output.xml

<child>
    <a>1</a>
    <b>3</b>
    <name>name</name>
    <foo>foo</foo>
</child>

但是我想要这样的东西:

<child>
    <foo>foo</foo>
    <parent>
        <a>1</a>
        <b>3</b>
        <name>name</name>
    </parent>
</child>

我希望有人能帮帮我。

您想要做的事情是可行的,但可能不值得麻烦。您将需要为您的Child类实现一个xmlapter,

package test;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public final class ChildAdapter extends
XmlAdapter<PrintedType, Child> {
    @Override
    public Child unmarshal(PrintedType v) throws Exception {
        Child ret = new Child();
        ret.setFoo(v.foo);
        ret.setA(v.parent.getA());
        ret.setB(v.parent.getB());
        ret.setName(v.parent.getName());
        return ret;
    }
    @Override
    public PrintedType marshal(Child v) throws Exception {
        PrintedType ret = new PrintedType();
        ret.parent = v;
        ret.foo = v.getFoo();
        return ret;
    }
}

以及生成您想要的XML表示的值类型:

package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="child")
@XmlAccessorType(XmlAccessType.FIELD)
public class PrintedType {
    String foo;
    Parent parent;
}

然后,如果您想封送Child的实例作为根元素(而不是在某些其他类中具有Child成员字段,并封送该类),您实际上必须首先将Child转换为PrintedType (https://stackoverflow.com/a/11967459/4854749)。因此,一个示例测试类可能是

package test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Demo {
    public static void main(String[] args) throws JAXBException {
        Child child = new Child();
        child.setA(1);
        child.setB(3);
        child.setName("name");
        child.setFoo("foo");
        JAXBContext jc = JAXBContext.newInstance(PrintedType.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        PrintedType ret = new PrintedType();
        ret.parent = child;
        ret.foo = child.getFoo();
        marshaller.marshal(ret, System.out);
    }
}

你确定这对你要解决的问题有意义吗?我不知道你的上下文,但问问你自己这些听起来更合适:Child 是一个 Parent,或Child 包含 Parent ?如果是后者,您可以通过取消继承和使用组合(使Child 包含一个Parent字段)使事情变得简单得多。这样您就不需要适配器类了,而且Child将完全按照您希望的方式封送。

最新更新