You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus 3.15中JAXB处理OffsetDateTime反序列化报错如何解决?

问题:Quarkus 3.15中JAXB反序列化XML到含OffsetDateTime的Java对象失败

使用Quarkus 3.15和JAXB将XML字符串反序列化为Java对象时,因对象包含OffsetDateTime类型属性,触发以下错误:

No default constructor found on class java.time.OffsetDateTime: java.lang.NoSuchMethodException: java.time.OffsetDateTime.<init>()
    at java.base/java.lang.Class.getConstructor0(Class.java:3585)
    at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)
    at org.glassfish.jaxb.core.v2.ClassFactory.tryGetDeclaredConstructor(ClassFactory.java:109)
    at org.glassfish.jaxb.core.v2.ClassFactory.create0(ClassFactory.java:78)
    at org.glassfish.jaxb.runtime.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:255)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:655)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:156)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:530)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:509)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:518)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:351)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2726)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:218)
    at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:189)
    at jakarta.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:152)
    at jakarta.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:205)

对应的Java对象示例:

@XmlRootElement(name="MyXmlPojo")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyXmlPojo {

    @XmlElement
    private String propA = null;

    @XmlElement
    private String propB = null;

    @XmlElement
    private OffsetDateTime dateProp = null;

    // 省略其他代码
}

解决方法:自定义JAXB适配器

由于OffsetDateTime无默认构造方法,JAXB无法直接实例化该类型对象,需通过XmlAdapter将其与字符串类型做双向转换:

  1. 编写适配器类
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class OffsetDateTimeAdapter extends XmlAdapter<String, OffsetDateTime> {
    // 使用ISO标准时间格式,可根据XML中的时间格式调整
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_OFFSET_DATE_TIME;

    @Override
    public OffsetDateTime unmarshal(String xmlDateTime) throws Exception {
        return xmlDateTime != null ? OffsetDateTime.parse(xmlDateTime, FORMATTER) : null;
    }

    @Override
    public String marshal(OffsetDateTime dateTime) throws Exception {
        return dateTime != null ? dateTime.format(FORMATTER) : null;
    }
}
  1. 在POJO的OffsetDateTime属性上添加注解,指定使用该适配器
@XmlRootElement(name="MyXmlPojo")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyXmlPojo {

    @XmlElement
    private String propA = null;

    @XmlElement
    private String propB = null;

    @XmlElement
    @XmlJavaTypeAdapter(OffsetDateTimeAdapter.class) // 添加此注解
    private OffsetDateTime dateProp = null;

    // 省略构造方法、getter/setter等
}

如果XML中的时间格式与ISO_OFFSET_DATE_TIME不符,只需修改适配器中的DateTimeFormatter为对应的格式即可。

内容的提问来源于stack exchange,提问作者Shadowman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:37:08