java解组-空值或缺少标记?

java解组-空值或缺少标记?,java,jaxb,xml-nil,Java,Jaxb,Xml Nil,在解组器设置的类中有一个可为零的字段: @XmlElement(name = "value", nillable = true) private BigDecimal valueVariable; 我的问题是,我无法判断xml元素是否被省略或设置为nil: A.XML文件中缺少元素,这不是必需的。 =>(valueVariable==null)为真 B.XML文件包含 =>(valueVariable==null)为真 如何判断非字符串变量的值是xsi:nil还是缺少标记 更新 你可以看到2个

在解组器设置的类中有一个可为零的字段:

@XmlElement(name = "value", nillable = true)
private BigDecimal valueVariable;
我的问题是,我无法判断xml元素是否被省略或设置为nil:

A.XML文件中缺少元素
,这不是必需的。
=>(valueVariable==null)为真

B.XML文件包含

=>(valueVariable==null)为真

如何判断非字符串变量的值是
xsi:nil
还是缺少标记

更新
你可以看到2个很好的解决方案,我更喜欢其中一个,但另一个也可以

这里有一个类似的问题:。似乎如果缺少元素,就不会调用setter方法。因此,您可以在方法中加入一些逻辑,以确定节点是否丢失或具有空值

@XmlElement(name = "value", nillable = true)
private BigDecimal valueVariable;

private boolean valueVariableMissing = true;

public void setValueVariable(BigDecimal valueVariable){
    this.valueVariable = valueVariable;
    this.valueVariableMissing = false;
}
基于
@xmlement
上的
nillable
设置,JAXB(JSR-222)实现可以将
null
表示为不存在的节点或可nillable元素。当您需要同时支持这两者或区分这两者时,您可以利用
JAXBElement

Java模型 根目录

类型为
JAXBElement
的字段/属性映射为
@xmlementref
注释。这对应于用
@XmlRegistry
注释的类上的
@xmlementdecl
注释

import java.math.BigDecimal;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElementRef(name="foo")
    JAXBElement<BigDecimal> foo;

    @XmlElementRef(name="bar")
    JAXBElement<BigDecimal> bar;

    @XmlElementRef(name="baz")
    JAXBElement<BigDecimal> baz;

}
输出

foo:缺席-空
bar:NIL-null
巴兹:价值-123.456
123.456

更新

如果您想维护现有的get/set方法,那么您可以像我在这个答案中所做的那样保持字段访问,并将访问器方法更改为如下所示:

public BigDecimal getBar() {
    if(null == bar) {
        return null;
    }
    return bar.getValue();
}

public void setBar(BigDecimal bar) {
    if(null == this.bar) {
        this.bar = new JAXBElement<BigDecimal>(new QName("bar"), BigDecimal.class, bar);
    } else {
        this.bar.setValue(bar);
    }
}
这种方法不要求您有权访问
解组器
。要确保拾取了
ObjectFactory
,您可以使用
@xmlseea
注释从一个域类引用它

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(ObjectFactory.class)
public class Root {

我在处理同一个问题, 为了修复它,我在封送对象时在包中创建了一个新文件:
“package info.java” 我在那里补充说:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://the.correct.namespace.com/gateway/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.the.package.name;

现在一切都好了

谢谢,这就是我需要的。但我的定义类似于私有JAXBElement-valueVariable,我不使用
@xmlementref
。我得到了错误:
在类javax.xml.bind.JAXBElement java.lang.NoSuchMethodException:javax.xml.bind.JAXBElement上找不到默认构造函数。(
顺便说一句,它是一个web服务,解组不受我控制。哦,现在我明白了,仅仅将
@xmlement
中私有变量的类型从
BigDecimal
更改为
JAXBElement
并不是一个解决方案。我也要去工厂。因此,从xsd…@user1414745生成java代码可能会更容易-我已经用一些您可能会发现有用的附加信息更新了我的答案。
public boolean isSetBar() {
    return null != bar;
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(ObjectFactory.class)
public class Root {
@javax.xml.bind.annotation.XmlSchema(namespace = "http://the.correct.namespace.com/gateway/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.the.package.name;