gpt4 book ai didi

java - 在动态 JSON 中序列化 null 和空字符串

转载 作者:IT老高 更新时间:2023-10-28 12:51:36 29 4
gpt4 key购买 nike

我有这个 JSON 内容:

{"color":null}

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

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

我当前的解决方案总是将 "color":null 反序列化为 空字符串。我找到了其他解决方案,而是将 null 或空字符串反序列化为 null

如何让 MOXy(或任何其他 jaxb 实现)将 null 反序列化为 null 并将空字符串反序列化为空字符串?


我正在使用此代码:

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<Entry> entries = new ArrayList<Entry>();
}

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", "<root><color xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"/></root>"));
Assert.assertEquals(null, unmarshall("json", "{\"color\":null}"));
}

/* All other tests are passing. */

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

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

@Test
public void marshallNull() throws Exception {
Assert.assertEquals("<color xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"/>", marshall("xml", null));
Assert.assertEquals("{\"color\":null}", marshall("json", null));
}

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

@Test
public void marshallValue() throws Exception {
Assert.assertEquals("<color>red</color>", 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:<null> but was:<>

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

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

我正在使用 MOXy 2.22.1 和 Java8(但与 2.182.192.20 的行为相同>、2.212.22)。我的 Maven pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>x</groupId>
<artifactId>x</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.22.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

最佳答案

有些事情你可能想尝试。

首先,尝试使用 @XmlElement(nillable=true) 代替 XmlNullPolicy 注释或设置 emptyNodeRepresentsNull 参数。

其次,您可能想编写自己的 XmlAdapter,它的作用几乎相同——将空字符串解码为 null。主要区别在于您还可以手动配置哪些字段将与您的适配器一起解码,哪些字段不会,因此保留当前行为。请引用此answer通过 Blaise Doughan 了解如何将自定义 XmlAdapter 连接到您的配置。

第三,据我所知 jackson 没有这个问题。见 this answer ot this wiki page关于如何为字段设置自定义反序列化器以防万一。

关于java - 在动态 JSON 中序列化 null 和空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34290137/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com