我有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;
}
}
答案 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();
}
}
<强>输出强>
JAXBContext
被VolunteerSession
引导时,显然它有必要的信息。JAXBContext
被超级SessionRecord
引导时,它不会引入VolunteerSession
。 JAXB将自动处理超类的元数据,但不会处理子类。在这种情况下,@XmlSeeAlso
通常用于引用映射的子类。VolunteerRecord
包含引用@XmlSeeAlso
的{{1}}注释。因此VolunteerSession
作为VolunteerSession
的一部分进行处理,并在编组时包含必要的信息。JAXBContext
答案 1 :(得分:1)
您必须在父类的@XmlSeeAlso注释中列出所有子类。