JAXB编组和继承

时间:2014-01-03 16:26:32

标签: java inheritance jaxb

我有2个类,一个扩展另一个。超类编组正确,但是添加一个属性的子类却没有。 XML中没有extra属性。

超类:

@XmlRootElement()
@XmlAccessorType(XmlAccessType.NONE)
public class SessionRecord extends Record {

  SimpleDateFormat hhmm = new SimpleDateFormat("HH:mm");
  SimpleDateFormat day = new SimpleDateFormat("EEEEE");

  @XmlAttribute protected int sessionId;
  @XmlAttribute protected boolean open;
  @XmlAttribute protected boolean night;
  protected Date start;
  protected Date finish;
  protected boolean setup;
  protected boolean takedown;

  @XmlAttribute
  public String getDescription() {
        if (start==null) start = new Date();
        if (finish==null) finish = new Date();
        return day.format(start)+(night ? " Night " : " ")+hhmm.format(start)+"-"+hhmm.format(finish)+" "+type();
  }

  private String type() {
        return setup ? "Setup" : (open ? "Open" : (takedown ? "Takedown" : ""));
  }

  @XmlAttribute
  public boolean isSetupTakedown() {
        return setup || takedown;
  }

}

这会产生类似于此的XML元素:

<sessionRecord setupTakedown="true" description="Saturday 09:00-13:00 Setup" night="false" open="false" sessionId="0"/>

没关系。

但是子类:

@XmlRootElement()
public class VolunteerSession extends SessionRecord {

  @XmlAttribute private boolean available;

}

生成相同的输出,available属性未编组。为什么JAXB没有编组额外的属性?

修改

进一步的信息:

记录超类只是这个:

public abstract class Record {}

这是表示顶级文档元素的类。它包含记录列表:

@XmlRootElement(name="response")
@XmlSeeAlso({
  RecordList.class, 
  VolunteerAssignment.class, 
  VolunteerRecord.class,
  SessionRecord.class,
  VolunteerSession.class,
  VolunteerArea.class,
  PossibleAssignment.class})
public class XMLResponse {

  @XmlAttribute private String errorMessage;

  private List<RecordList<? extends Record>> recordLists  = new ArrayList<RecordList<? extends Record>>();

  //snip...

  public void setError(String errorMessage) {
        this.errorMessage = errorMessage;
  }

  @XmlMixed
  public List<RecordList<? extends Record>> getRecordLists() {
        return recordLists;
  }

}

最后,RecordList

@XmlRootElement()
public class RecordList<T extends Record> {

  @XmlAttribute private String name;
  @XmlAttribute private int total;
  @XmlAttribute private int count;
  @XmlAttribute private int start;
  @XmlAttribute private boolean update;
  private List<T> records;

  // snip constructors, setters

  @XmlMixed
  public List<T> getRecords() {
        return records;
  }

}

2 个答案:

答案 0 :(得分:2)

听起来似乎VolunteerSession类未包含在JAXBContext中。这可能会发生,具体取决于您创建JAXBContext的方式。下面是一些示例代码,其中基于3个不同的JAXBContext实例编组相同的对象,每个实例都从不同的类引导。

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        VolunteerSession volunteerSession = new VolunteerSession();

        marshal(VolunteerSession.class, volunteerSession);
        marshal(SessionRecord.class, volunteerSession);
        marshal(XMLResponse.class, volunteerSession);
    }

    private static void marshal(Class bootstrapClass, Object object) throws Exception {
        System.out.println(bootstrapClass.getName());
        JAXBContext jc = JAXBContext.newInstance(bootstrapClass);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(object, System.out);
        System.out.println();
    }

}

<强>输出

  1. JAXBContextVolunteerSession引导时,显然它有必要的信息。
  2. JAXBContext被超级SessionRecord引导时,它不会引入VolunteerSession。 JAXB将自动处理超类的元数据,但不会处理子类。在这种情况下,@XmlSeeAlso通常用于引用映射的子类。
  3. VolunteerRecord包含引用@XmlSeeAlso的{​​{1}}注释。因此VolunteerSession作为VolunteerSession的一部分进行处理,并在编组时包含必要的信息。
  4. JAXBContext

答案 1 :(得分:1)

您必须在父类的@XmlSeeAlso注释中列出所有子类。

相关问题