JAXB从子类中的父类“重命名”属性

时间:2018-01-24 15:21:10

标签: java jaxb

如果我有父类A

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
class A {
    private int id;
}

和一个儿童班B

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
class B extends A {
    private int x;
    private int y;
    private int z;
}

在系统中还有许多类C,D,X,Y,Z,它们扩展了A类。

我想将属性A#id“重命名”为B#somethingId,仅用于B的实例。

我的想法是重新声明字段ID并使用XmlTransient但它不起作用,我在编组B时仍然有“id”:

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
class B extends a {
    private int x;
    private int y;
    private int z;

    public Long getSomethingId() {
        return id;
    }

    @XmlElement
    public void setSomethingId(Long id) {
        super.setId(id);
    }   

    public Long getId() {
        return super.getId();
    }

    @XmlTransient
    public void setId(Long id) {
        super.setId(id);
    }

}

输出

   <B>
          <id>
          <somethingId>
          ...

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

试试这个:

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name= "B")
public class B extends A {
    private int x;
    private int y;
    private int z;


    @Override
    public int getId() {
        return super.getId();
    }

    @Override
    @XmlElement(name = "somethingId")
    public void setId(int id) {
        super.setId(id);
    }

}

@XmlType
@XmlAccessorType(XmlAccessType.PROPERTY)
public class A {
    private int id;

    public int getId() {
        return id;
    }

    @XmlTransient
    public void setId(int id) {
        this.id = id;
    }
}

请注意,@ XmlAccessorType设置为XmlAccessType.PROPERTY。

或者您也可以使用XmlAccessType.FIELD执行此操作,如下所示:

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class A {
    @XmlTransient
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name= "B")
public class B extends A {
    private int x;
    private int y;
    private int z;

    @Override
    public int getId() {
        return super.getId();
    }

    @Override
    @XmlElement(name = "somethingId")
    public void setId(int id) {
        super.setId(id);
    }

}

编辑以回复评论:

您当然可以将ID保存在所需的类中。例如,按照第二种方法,添加类如:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name= "C")
public class C extends A {
    private int j;
    private int k;

    @Override
    public int getId() {
        return super.getId();
    }

    @Override
    @XmlElement(name = "id")
    public void setId(int id) {
        super.setId(id);
    }

}

会工作得很好。如果我用一个简单的主要来演示它:

public static void main(String[] args) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(B.class, C.class);
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            B b = new B();
            b.setId(1);
            marshaller.marshal(b, System.out);

            System.out.println();

            C c = new C();
            c.setId(2);
            marshaller.marshal(c, System.out);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

会给你以下结果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<B>
    <x>0</x>
    <y>0</y>
    <z>0</z>
    <somethingId>1</somethingId>
</B>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<C>
    <j>0</j>
    <k>0</k>
    <id>2</id>
</C>

或者这种方法中你不喜欢的东西?