JAXB序列化异常排查:propOrder中creationDate不存在及日期字段丢失
问题解决
一、creationDate在propOrder中引发异常的原因及修复
原因
JAXB默认采用XmlAccessType.PROPERTY的属性访问策略,即通过getter/setter方法识别JavaBean属性,而非直接识别字段。你的MusicBand类未显式指定@XmlAccessorType,JAXB会校验propOrder中的每个属性是否存在对应getter方法。如果creationDate字段没有配套的getCreationDate()方法,JAXB会判定该属性不存在,进而抛出异常。
修复方案
两种可选方式:
- 为
creationDate添加标准getter/setter方法
public java.util.Date getCreationDate() { return creationDate; } public void setCreationDate(java.util.Date creationDate) { this.creationDate = creationDate; }
- 给
MusicBand类添加@XmlAccessorType(XmlAccessType.FIELD)注解,让JAXB直接通过字段识别属性,无需依赖getter/setter:
@XmlType(propOrder = {"id","name","coordinates", "numberOfParticipants", "creationDate", "albumsCount", "establishmentDate", "genre", "label"}) @XmlAccessorType(XmlAccessType.FIELD) // 添加该注解 public class MusicBand implements Comparable<MusicBand> { // 原有字段定义... }
二、establishmentDate(ZonedDateTime)编组为空的原因及修复
原因
JAXB(GlassFish实现版本)默认不支持Java 8引入的java.time.ZonedDateTime等新时间类型,无法自动完成该类型的XML序列化,因此输出空标签。
修复方案
自定义XmlAdapter实现ZonedDateTime与XML字符串的转换:
- 编写适配器类:
import jakarta.xml.bind.annotation.adapters.XmlAdapter; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class ZonedDateTimeAdapter extends XmlAdapter<String, ZonedDateTime> { // 使用ISO标准时间格式,可根据需求自定义 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_ZONED_DATE_TIME; @Override public ZonedDateTime unmarshal(String xmlValue) throws Exception { return ZonedDateTime.parse(xmlValue, FORMATTER); } @Override public String marshal(ZonedDateTime dateTime) throws Exception { return dateTime != null ? dateTime.format(FORMATTER) : null; } }
- 在
MusicBand的establishmentDate字段上添加@XmlJavaTypeAdapter注解:
@XmlJavaTypeAdapter(ZonedDateTimeAdapter.class) private java.time.ZonedDateTime establishmentDate;
完成上述修改后,重新执行编组操作,establishmentDate会正常生成XML内容,同时creationDate也能在propOrder中正常使用而不触发异常。
内容的提问来源于stack exchange,提问作者keks
相关产品推荐
相关产品推荐

