当前位置:  开发笔记 > 编程语言 > 正文

在动态JSON中序列化空值和空字符串

如何解决《在动态JSON中序列化空值和空字符串》经验,为你挑选了1个好方法。

我有这个JSON内容:

{"color":null}

我想用它来制作这些Java对象(反之亦然):

Container
|- List entries
   |- Entry
      |- String key = "color"
      |- String value = null

我目前的解决方案总是反序列化"color":null到一个空字符串.我找到了其他解决方案,而不是反序列化null或将String清空null.

我怎样才能获得莫西(或任何其他JAXB实现)反序列化nullnull空字符串为空字符串?


我正在使用此代码:

import java.io.ByteArrayOutputStream;
import java.util.*;

import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

import org.eclipse.persistence.internal.oxm.ByteArraySource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.oxm.annotations.*;
import org.junit.*;

class Container {

    @XmlVariableNode("key")
    List entries = new ArrayList();   
}

class Entry {

    @XmlTransient
    public String key;

    @XmlValue
    @XmlNullPolicy(nullRepresentationForXml=XmlMarshalNullRepresentation.XSI_NIL, xsiNilRepresentsNull=false)
    public String value;
}

public class D {

    /** THIS TEST FAILS!!! */

    @Test
    public void unmarshallNull() throws Exception {
        Assert.assertEquals(null, unmarshall("xml", ""));
        Assert.assertEquals(null, unmarshall("json", "{\"color\":null}"));
    }

    /* All other tests are passing. */

    @Test
    public void unmarshallEmpty() throws Exception {
        Assert.assertEquals("", unmarshall("xml", ""));
        Assert.assertEquals("", unmarshall("json", "{\"color\":\"\"}"));
    }

    @Test
    public void unmarshallValue() throws Exception {
        Assert.assertEquals("red", unmarshall("xml", "red"));
        Assert.assertEquals("red", unmarshall("json", "{\"color\":\"red\"}"));
    }

    @Test
    public void marshallNull() throws Exception {
        Assert.assertEquals("", marshall("xml", null));
        Assert.assertEquals("{\"color\":null}", marshall("json", null));
    }

    @Test
    public void marshallEmpty() throws Exception {
        Assert.assertEquals("", marshall("xml", ""));
        Assert.assertEquals("{\"color\":\"\"}", marshall("json", ""));
    }

    @Test
    public void marshallValue() throws Exception {
        Assert.assertEquals("red", marshall("xml", "red"));
        Assert.assertEquals("{\"color\":\"red\"}", marshall("json", "red"));
    }

    private static String marshall(String format, String value) throws JAXBException {

        // prepare
        JAXBContext jc = JAXBContext.newInstance(Container.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, "application/"+format);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(JAXBContextProperties.JSON_INCLUDE_ROOT, false);

        // define example data
        Container detail = new Container();
        Entry entry = new Entry();
        entry.key = "color";
        entry.value = value;
        detail.entries.add(entry);

        // marshall
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        marshaller.marshal(detail, outputStream);
        return outputStream.toString();
    }

    private static String unmarshall(String format, String raw) throws JAXBException {

        // prepare
        JAXBContext jc = JAXBContext.newInstance(Container.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, "application/"+format);
        unmarshaller.setProperty(JAXBContextProperties.JSON_INCLUDE_ROOT, false);

        // unmarshall
        Container container = unmarshaller.unmarshal(new ByteArraySource(raw.getBytes()), Container.class).getValue();
        return container.entries.get(0).value;
    }
}

它适用于XML但不适用于JSON:

Test failure: unmarshallNull
java.lang.AssertionError: expected: but was:<>

我还将MOXy配置为相关包(jaxb.properties)的jaxb-provider :

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

我使用MOXy 2.22.1和Java8(但具有相同的行为2.18,2.19,2.20,2.21,2.22).我的妈妈pom.xml:


    4.0.0
    x
    x
    0.0.1-SNAPSHOT
    
        
            org.glassfish.jersey.media
            jersey-media-moxy
            2.22.1
        
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    1.8
                    1.8
                
            
        
    

Jeor Mattan.. 5

有些事情你可能想尝试.

首先,尝试使用@XmlElement(nillable=true)而不是XmlNullPolicy注释或设置emptyNodeRepresentsNull参数.

其次,你可能想编写自己的东西XmlAdapter,这几乎可以做同样的事情 - 将空字符串unmarshall为null.主要区别在于您还可以手动配置哪些字段将使用适配器解组,哪些不会,因此保留当前行为.请参阅Blaise Doughan的回答,看看如何将自定义连接XmlAdapter到您的配置.

第三,据我所知杰克逊没有这个问题.见这个答案加时赛此Wiki网页有关如何设置自定义解串器的情况下,它的字段.



1> Jeor Mattan..:

有些事情你可能想尝试.

首先,尝试使用@XmlElement(nillable=true)而不是XmlNullPolicy注释或设置emptyNodeRepresentsNull参数.

其次,你可能想编写自己的东西XmlAdapter,这几乎可以做同样的事情 - 将空字符串unmarshall为null.主要区别在于您还可以手动配置哪些字段将使用适配器解组,哪些不会,因此保留当前行为.请参阅Blaise Doughan的回答,看看如何将自定义连接XmlAdapter到您的配置.

第三,据我所知杰克逊没有这个问题.见这个答案加时赛此Wiki网页有关如何设置自定义解串器的情况下,它的字段.

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有