JAXB return null instead empty string

后端 未结 2 1691
醉梦人生
醉梦人生 2021-02-03 13:35

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

         


        
相关标签:
2条回答
  • 2021-02-03 14:02

    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.

    0 讨论(0)
  • 2021-02-03 14:11

    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
    
    0 讨论(0)
提交回复
热议问题