gpt4 book ai didi

java - 为什么 JAXB 需要一个无参数构造函数来编码?

转载 作者:IT老高 更新时间:2023-10-28 20:40:26 25 4
gpt4 key购买 nike

如果您尝试编码一个引用了没有无参数构造函数的复杂类型的类,例如:

import java.sql.Date;

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
int i;
Date d; //java.sql.Date does not have a no-arg constructor
}

使用作为 Java 一部分的 JAXB 实现,如下所示:

    Foo foo = new Foo();
JAXBContext jc = JAXBContext.newInstance(Foo.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(foo, baos);

JAXB 会抛出一个

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.sql.Date does not have a no-arg default constructor

现在,我明白了为什么 JAXB 在解码时需要一个无参数构造函数——因为它需要实例化对象。但是为什么 JAXB 在编码时需要一个无参数的构造函数呢?

另外,另一个傻瓜,如果字段为空,为什么 Java 的 JAXB 实现会抛出异常,并且无论如何都不会被编码?

我是否遗漏了什么,或者这些只是 Java 的 JAXB 实现中的错误实现选择?

最佳答案

当一个 JAXB (JSR-222)实现初始化它的元数据,它确保它可以支持编码和解码。

对于没有无参数构造函数的 POJO 类,您可以使用类型级别的 XmlAdapter 来处理它:

java.sql.Date 默认不支持(尽管在 EclipseLink JAXB (MOXy) 中支持)。这也可以使用通过 @XmlJavaTypeAdapter 在字段、属性或包级别指定的 XmlAdapter 来处理:


Also, another nit, why does Java's JAXB implementation throw an exception if the field is null, and isn't going to be marshalled anyway?

您看到了什么异常?通常,当字段为 null 时,它不会包含在 XML 结果中,除非它使用 @XmlElement(nillable=true) 进行注释,在这种情况下,元素将包含 xsi:nil="true "


更新

您可以执行以下操作:

SqlDateAdapter

下面是一个 XmlAdapter,它将从您的 JAXB 实现不知道如何处理的 java.sql.Date 转换为 java.util .Date 它的作用:

package forum9268074;

import javax.xml.bind.annotation.adapters.*;

public class SqlDateAdapter extends XmlAdapter<java.util.Date, java.sql.Date> {

@Override
public java.util.Date marshal(java.sql.Date sqlDate) throws Exception {
if(null == sqlDate) {
return null;
}
return new java.util.Date(sqlDate.getTime());
}

@Override
public java.sql.Date unmarshal(java.util.Date utilDate) throws Exception {
if(null == utilDate) {
return null;
}
return new java.sql.Date(utilDate.getTime());
}

}

Foo

XmlAdapter 是通过 @XmlJavaTypeAdapter 注解注册的:

package forum9268074;

import java.sql.Date;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
int i;

@XmlJavaTypeAdapter(SqlDateAdapter.class)
Date d; //java.sql.Date does not have a no-arg constructor
}

关于java - 为什么 JAXB 需要一个无参数构造函数来编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9268074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com