我有这个JSON内容:
{"color":null}
我想用它来制作这些Java对象(反之亦然):
Container |- Listentries |- Entry |- String key = "color" |- String value = null
我目前的解决方案总是反序列化"color":null
到一个空字符串.我找到了其他解决方案,而不是反序列化null
或将String清空null
.
我怎样才能获得莫西(或任何其他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") Listentries = 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", " ")); Assert.assertEquals("red", unmarshall("json", "{\"color\":\"red\"}")); } @Test public void marshallNull() throws Exception { Assert.assertEquals(" red ", 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
Jeor Mattan.. 5
有些事情你可能想尝试.
首先,尝试使用@XmlElement(nillable=true)
而不是XmlNullPolicy
注释或设置emptyNodeRepresentsNull
参数.
其次,你可能想编写自己的东西XmlAdapter
,这几乎可以做同样的事情 - 将空字符串unmarshall为null.主要区别在于您还可以手动配置哪些字段将使用适配器解组,哪些不会,因此保留当前行为.请参阅Blaise Doughan的回答,看看如何将自定义连接XmlAdapter
到您的配置.
第三,据我所知杰克逊没有这个问题.见这个答案加时赛此Wiki网页有关如何设置自定义解串器的情况下,它的字段.
有些事情你可能想尝试.
首先,尝试使用@XmlElement(nillable=true)
而不是XmlNullPolicy
注释或设置emptyNodeRepresentsNull
参数.
其次,你可能想编写自己的东西XmlAdapter
,这几乎可以做同样的事情 - 将空字符串unmarshall为null.主要区别在于您还可以手动配置哪些字段将使用适配器解组,哪些不会,因此保留当前行为.请参阅Blaise Doughan的回答,看看如何将自定义连接XmlAdapter
到您的配置.
第三,据我所知杰克逊没有这个问题.见这个答案加时赛此Wiki网页有关如何设置自定义解串器的情况下,它的字段.