【问题标题】:Java xml serialization null handlingJava xml 序列化 null 处理
【发布时间】:2011-05-25 20:35:56
【问题描述】:

我正在使用 JAXB2 将对象序列化为 xml。

有没有办法强制它创建整个对象结构,如下例所示,即使它没有填充支持对象?

即使没有设置 asignee 属性,这也是我的预期结果。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<note>
    <to xsi:nil="true"/>
    <from xsi:nil="true"/>
    <header xsi:nil="true"/>
    <body>text</body>
    <assignee>
        <name xsi:nil="true"/>
        <surname xsi:nil="true"/>
    </assignee>
</note>

我使用以下代码进行序列化:

JAXBContext jc = JAXBContext.newInstance(dataObject.getClass());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
marshaller.marshal(dataObject, outputStream);

【问题讨论】:

    标签: java xml serialization jaxb jaxb2


    【解决方案1】:

    您可以执行以下操作:

    注意

    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    
    @XmlRootElement
    @XmlType(propOrder={"to", "from", "header", "body", "assignee"})
    public class Note {
    
        private String to;
        private String from;
        private String header;
        private String body;
        private Assignee assignee;
    
        @XmlElement(nillable=true)
        public String getTo() {
            return to;
        }
    
        public void setTo(String to) {
            this.to = to;
        }
    
        @XmlElement(nillable=true)
        public String getFrom() {
            return from;
        }
    
        public void setFrom(String from) {
            this.from = from;
        }
    
        @XmlElement(nillable=true)
        public String getHeader() {
            return header;
        }
    
        public void setHeader(String header) {
            this.header = header;
        }
    
        @XmlElement(nillable=true)
        public String getBody() {
            return body;
        }
    
        public void setBody(String body) {
            this.body = body;
        }
    
        public Assignee getAssignee() {
            return assignee;
        }
    
        public void setAssignee(Assignee assignee) {
            this.assignee = assignee;
        }
    
    }
    

    受让人

    当未编组的 Assignee 实例应被解释为 null 时,我们需要有一种方法来拒绝。我添加了一个 isNull() 方法,如果所有字段都为空,则返回 true。

    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    @XmlJavaTypeAdapter(AssigneeAdapter.class)
    public class Assignee {
    
        private String name;
        private String surname;
    
        @XmlElement(nillable=true)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @XmlElement(nillable=true)
        public String getSurname() {
            return surname;
        }
    
        public void setSurname(String surname) {
            this.surname = surname;
        }
    
        public boolean isNull() {
            return null == name && null == surname;
    
        }
    }
    

    AssigneeAdapter

    AssigneeAdapter 使用 Assignee 对象作为值类型和绑定类型。这个类利用了我们在 Assignee 上添加的 isNull() 方法:

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    public class AssigneeAdapter extends XmlAdapter<Assignee, Assignee> {
    
        @Override
        public Assignee unmarshal(Assignee v) throws Exception {
            if(v.isNull()) {
                return null;
            }
            return v;
        }
    
        @Override
        public Assignee marshal(Assignee v) throws Exception {
            if(null == v) {
                return new Assignee();
            }
            return v;
        }
    
    }
    

    演示

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Note.class);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(new Note(), System.out);
        }
    }
    

    有关 XmlAdapter 的更多信息,请参阅:

    【讨论】:

    • 非常感谢!看起来@XmlJavaTypeAdapter 让我很开心。
    【解决方案2】:

    【讨论】:

    • JAXBElement 在您需要区分为什么您的值为 null(缺少元素或 xsi:nil="true" 存在的元素)时很有用。如果您总是想用 xsi:nil="true" 表示 null,那么您可以使用 @XmlElement(nillable=true)。看看我的回答:stackoverflow.com/questions/4449284/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多