JAXB返回null而不是空字符串

MyT*_*tle 7 java jaxb

null当解组时,如果XML属性值为空,我如何检索值?现在我在我的getter里面检查null:

public String getLabel() {
    if (label.isEmpty()) {
        return null;
    }
    else {
        return label;
    }
}
Run Code Online (Sandbox Code Playgroud)

但可能存在一些其他更优雅的方式?

谢谢.

npe*_*npe 10

我认为你的XML看起来或多或少是这样的:

    <myElement></myElement>
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这意味着您传递的一个空字符串.

如果你想通过,null你有两个选择:

  1. 根本不要传递此标记(您的XML根本不应包含<myElement/>标记).
  2. 使用xsi:nil.

如果使用xsi:nil,首先你必须声明你的xml元素(在XSD文件中)nilable,如下所示:

    <xsd:element name="myElement" nillable="true"/>
Run Code Online (Sandbox Code Playgroud)

然后,要传递nullXML中的值,请执行以下操作:

    <myElement xsi:nil="true"/>
Run Code Online (Sandbox Code Playgroud)

或这个:

    <myElement xsi:nil="true"></myElement>
Run Code Online (Sandbox Code Playgroud)

这样,JAXB知道,您传递的是null而不是空字符串.


bdo*_*han 7

npe给出的答案是一个很好的答案,并指定你想要null表达的方式也是我的建议.要进行xsi:nil编组,您需要将属性注释为(请参阅绑定到JSON和XML - 处理空):

@XmlElement(nillable=true)
public String getLabel() {
    return label;
}
Run Code Online (Sandbox Code Playgroud)

如果您不想更改XML表示,那么您可以使用XmlAdapter:

EmptyStringAdapter

package forum10869748;

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

public class EmptyStringAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        if("".equals(v)) {
            return null;
        }
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        return v;
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以XmlAdapter通过使用@XmlJavaTypeAdapter注释来引用.如果您希望将此XmlAdapter应用于所有字符串,则可以在包级别注册它(请参阅JAXB和包级别XmlAdapters).

package forum10869748;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Foo {

    private String label;

    @XmlJavaTypeAdapter(EmptyStringAdapter.class)
    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

}
Run Code Online (Sandbox Code Playgroud)

演示

package forum10869748;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10869748/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        System.out.println(foo.getLabel());
    }

}
Run Code Online (Sandbox Code Playgroud)

input.xml中

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <label></label>
</foo>
Run Code Online (Sandbox Code Playgroud)

产量

null
Run Code Online (Sandbox Code Playgroud)

  • 非常有用的一段代码 - 作为您可以使用“JAXB”做什么的示例。但在我看来,你在这里提出的建议是危险的。将空字符串视为空值,而不通知合同中可能存在空值(“WSDL”、“XSD”)是一种猴子修补,并且几乎可以肯定,有一天有人会在调试时感到非常非常沮丧。如果您想将空字符串和空值视为相同,我建议使用 [isBlank(String) from commons-lang](http://commons.apache.org/lang/api-2.5/org/apache/commons/ lang/StringUtils.html#isBlank%28java.lang.String%29) (2认同)
  • @npe - 我同意指定`@XmlElement(nillable = true)`并在XML中显式表示null是最好的方法(我甚至赞成你的答案).我为这些人添加了这个答案如何不能改变XML表示.只要用户与空元素的含义一致,我认为它不危险. (2认同)