简体   繁体   中英

JAXB return null instead empty string

How I can retrieve null value, when unmarshalling, if inside XML attribute value is empty ? Now I make inside my getters checking for null :

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

But may be exist some other, more elegant way?

Thanks.

I think your XML looks more or less like this:

    <myElement></myElement>

This, unfortunately, means, that you are passing an empty string .

If you want to pass null you have two options:

  1. Do not pass this tag at all (your XML should not contain <myElement/> tag at all).
  2. Use xsi:nil .

If using xsi:nil , first you have to declare your xml element (in XSD file) as nilable , like this:

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

Then, to pass the null value inside XML do this:

    <myElement xsi:nil="true"/>

or this:

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

This way, JAXB knows, that you are passing null instead of an empty String.

The answer given by npe is a good one, and specifying how you want null represented would be my recommendation as well. To have xsi:nil marshalled you will want to annotate your property as (see Binding to JSON & XML - Handling Null ):

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

If you don't want to change your XML representation then you could use an 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;
    }

}

Foo

You reference an XmlAdapter through the use of the @XmlJavaTypeAdapter annotation. If you would like this XmlAdapter applied to all Strings then you could register it at the package level (see JAXB and Package Level 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;
    }

}

Demo

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

}

input.xml

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

Output

null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM