Java JAXB编组和继承

Java JAXB编组和继承,java,inheritance,jaxb,Java,Inheritance,Jaxb,我有两个类,一个扩展另一个。超类封送正确,但添加了一个属性的子类则不正确。XML中不存在额外属性 超类: @XmlRootElement() @XmlAccessorType(XmlAccessType.NONE) public class SessionRecord extends Record { SimpleDateFormat hhmm = new SimpleDateFormat("HH:mm"); SimpleDateFormat day = new SimpleDateF

我有两个类,一个扩展另一个。超类封送正确,但添加了一个属性的子类则不正确。XML中不存在额外属性

超类:

@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"/>
如果生成相同的输出,则不会封送
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;
  }

}
@XmlRootElement(name=“response”)
@XmlSeeAllow({
RecordList.class,
自愿者类,
志愿者记录类,
SessionRecord.class,
志愿者课程,
志愿者区域。班级,
possibleasignment.class})
公共类XMLResponse{
@XmlAttribute私有字符串错误消息;

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

听起来好像
自愿者会话
类没有包含在
JAXBContext
中。这可能会发生,具体取决于您如何创建
JAXBContext
。下面是一些示例代码,其中相同的对象是marsha基于
JAXBContext
的3个不同实例,每个实例从不同的类中引导

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();
    }

}
输出

  • JAXBContext
    autonovateSession
    启动时,显然它有必要的信息
  • JAXBContext
    从超类
    SessionRecord
    启动时,它不会拉入
    session
    。JAXB将自动处理超类的元数据,而不是子类的元数据。在这种情况下,
    @xmlseea
    通常用于引用映射的子类
  • 志愿者记录
    包含一个引用
    志愿者会话
    @xmlSee
    注释。因此
    志愿者会话
    作为
    JAXBContext
    的一部分进行处理,并在封送时包含必要的信息
  • forum20908213.session
    forum20908213.会议记录
    forum20908213.XMLResponse
    
    尝试在您的志愿者会话类中添加可用的getter和setter。尝试了之后,没有什么区别您可以添加您的
    Record
    类以及如何创建
    JAXBContext
    ?根据请求添加了额外的信息。实际上@xmlsee也在XMLResponse中,不像我前面所说的那样记录,但这不会产生太大的影响事实上,我已经这样做了。对不起,我应该说得很清楚。它在
    Record
    超类中,在
    SessionRecord
    +1-您也可以将它们作为用于引导
    JAXBContext
    的类列表传递进来。根据请求添加了额外的信息。实际上@xmlsee也在XMLResponse中,而不是我前面说过的记录,但这应该不会让dirrerenceworking现在变得很好。我不知道我做了什么,但出于某种奇怪的原因,SessionRecord的XML表示还包含了available属性。不过这并不重要。+1这很有趣。我认为我无法访问编组代码本身,因为Spring MVC已经为我完成了所有这些。@NickJ-我认为解决您问题的方法是在
    记录
    会话记录
    中添加一个
    @xmlseea
    ,并引用
    志愿者会话
    。我试图在回答中指出的一点是,基于
    JAXBContext
    的创建方式,可以创建不同的元数据。
    @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;
      }
    
    }
    
    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();
        }
    
    }