JAXB возвращает null вместо пустой строки

как я могу получить null значение, когда unmarshalling, если внутри значения атрибута XML пусто ? Теперь я делаю внутри моих геттеров проверку на null :

public String getLabel() {
    if (label.isEmpty()) {
        return null;
    }
    else {
        return label;
    }
}

но может быть существует какой-то другой, более элегантный способ?

спасибо.

2 ответов


Я думаю, что ваш XML выглядит примерно так:

    <myElement></myElement>

это, к сожалению, означает, что ты передача пустой строки.

если вы хотите передать null у вас есть два варианта:

  1. не передавайте этот тег вообще (ваш XML не должен содержать <myElement/> tag вообще).
  2. использовать xsi:nil.

при использовании xsi:nil, сначала вы должны объявить свой xml-элемент (в XSD-файле) как nilable, вот так:

    <xsd:element name="myElement" nillable="true"/>

затем, чтобы пройти null значение внутри XML сделайте следующее:

    <myElement xsi:nil="true"/>

или такой:

    <myElement xsi:nil="true"></myElement>

таким образом, JAXB не знает, что вы передаете null вместо пустой строки.


на ответ, данный npe является хорошим, и указав, как вы хотите null представлена будет моя рекомендация, а также. Иметь xsi:nil marshalled вы захотите аннотировать свою собственность как (см. привязка к JSON & XML-обработка Null):

@XmlElement(nillable=true)
public String getLabel() {
    return label;
}

если вы не хотите изменять свое 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;
    }

}

Фу

ссылка на 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;
    }

}

демо

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());
    }

}

вход.в XML

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <label></label>
</foo>

выход

null