gpt4 book ai didi

java - 使用 XMLAdapter 时 JAXB 无法编码(marshal) null 值

转载 作者:太空宇宙 更新时间:2023-11-04 14:32:50 24 4
gpt4 key购买 nike

我在源代码中使用 Guava 可选字段,并且想要将使用可选的对象编码(marshal)至 xml,因此我使用了 JAXB。

我为此创建了一个XMLAdapter:

public abstract class OptionalAdpater<T> extends XmlAdapter<T, Optional<T>> {

@Override
public Optional<T> unmarshal(T v) throws Exception {
return Optional.of(v);
}

@Override
public T marshal(Optional<T> v) throws Exception {
if (v == null) {
return null;
}

return v.isPresent() ? v.get() : null;
}
}

但是当我在类里面使用它时

@XmlRootElement(name = "test")
public class Test {

private Optional<Integer> optionalValue = Optional.absent();

@XmlElement(name = "optional-value", type = Integer.class)
@XmlJavaTypeAdapter(type = Integer.class, value = OptionalIntegerAdapter.class)
public Optional<Integer> getOptionalValue() {
return optionalValue;
}

public void setOptionalValue(Optional<Integer> optionalValue) {
this.optionalValue = optionalValue;
}
}

JAXB 失败并出现 NullPointerException。我不明白的是,如果我不使用可选类型而只使用盒装整数并且值为 null 那么 JAXB 会跳过对该字段的编码,但当我使用适配器类型可选。

追踪:

Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$17.print(RuntimeBuiltinLeafInfoImpl.java:717)
at com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$17.print(RuntimeBuiltinLeafInfoImpl.java:711)
at com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$StringImpl.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:149)
at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:241)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:114)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:341)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:582)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:323)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:103)

最佳答案

这是罪魁祸首的代码:

        primaryList.add(new StringImpl<Integer>(Integer.class,
createXS("int"),
createXS("unsignedShort")
) {
public Integer parse(CharSequence text) {
return DatatypeConverterImpl._parseInt(text);
}

public String print(Integer v) {
return DatatypeConverterImpl._printInt(v);
}
});

_printInt接受int因此,如果返回空整数,则隐式拆箱。

为什么它在没有适配器/可选的情况下也能工作,可能是因为可选的。某处可能有一些逻辑检查 null 的属性。你没有null ,您有 Optional .

从我的角度来看,这是 JAXB 中的一个错误。运行时应检查 null在适配器转换它们之后,而不是之前。

如何解决它 - 我认为目前唯一的方法是调整您的 Optional<Integer>到字符串而不是 Integer .

关于java - 使用 XMLAdapter 时 JAXB 无法编码(marshal) null 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25932803/

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