简体   繁体   English

Jackson:自定义反序列化器:无法使用数组反序列化 XML

[英]Jackson: custom deserializer: cannot deserialize XML with array

I use Jackson to serialize one of my classes as XML.我使用 Jackson 将我的一个类序列化为 XML。 Because of the complex internal structure, I use a custom serializer that generates this data as an array.由于内部结构复杂,我使用自定义序列化程序将这些数据生成为数组。

The resulting XML looks like this in a simplified example:生成的 XML 在一个简化示例中如下所示:

<MyDataType>
    <list>
        <entry>
            <order>0</order>
            <value>And then a step to the right</value>
        </entry>
        <entry>
            <order>1</order>
            <value>It's just a jump to the left</value>
        </entry>
        <entry>
            <order>2</order>
            <value>With your hands on your hips</value>
        </entry>
    </list>
</MyDataType>

I only get problems when I deserialize.我只有在反序列化时才会遇到问题。 Then jsonParser.getCodec().readTree(jsonParser) just "sees" the last entry of the array.然后jsonParser.getCodec().readTree(jsonParser)只是“看到”数组的最后一个条目。 All other entries are lost.所有其他条目都将丢失。

So the debug output in the deserializer will show:所以解串器中的调试输出将显示:

Deserialize: Incoming data:
{
    "list": {
        "entry": {
            "order": "2",
            "value": "With your hands on your hips"
        }
    }
}

Even more weird: If I serialize/deserialize to JSON, the same code works fine!更奇怪的是:如果我将序列化/反序列化为 JSON,相同的代码就可以正常工作!

Deserializer:解串器:

class MyDataTypeDeserialize extends JsonDeserializer<MyDataType> {
    @Override
    public MyDataType deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        MyDataType result = new MyDataType();

        JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);

        // Shows only one entry when using XML
        System.out.println("Deserialize: Incoming data: " + rootNode.toString());

        JsonNode valueList = rootNode.get("list");
        JsonNode entryList = valueList.findValue("entry");

        for (Iterator<JsonNode> it = entryList.elements(); it.hasNext(); ) {
            JsonNode element = it.next();

            int order = element.get("order").asInt();
            String value = element.get("value").asText();

            result.addValue(order, value);
        }

        return result;
    }
}

Any hints what I'm doing wrong will be appreciated.任何提示我做错了什么都将不胜感激。

[Edited] [编辑]

I ran into the same issue a couple of years back.几年前我遇到了同样的问题。 By default Jackson (most specifically the UntypedObjectDeserializer) when sees multiple children with the same name it does not map them into an array or list.默认情况下,Jackson(最特别的是 UntypedObjectDeserializer)在看到多个同名的孩子时,它不会将它们映射到数组或列表中。 What I did is I used this library: https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22 With that you can do:我所做的是我使用了这个库: https : //search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22可以做:

JSONObject jsonObject = XML.toJSONObject(...);
String jsonText = jsonObject.toString();
// Use Jackson here

Of course this is an additional parsing and then serialization step before you can actually deserialize as a Jackson node.当然,在您实际反序列化为 Jackson 节点之前,这是一个额外的解析和序列化步骤。 The above worked fine for me, because it wasn't on the critical path of the application.以上对我来说效果很好,因为它不在应用程序的关键路径上。

[Edit] [编辑]

In your case where you need to use JsonParser in a deserializer you could try something like this:在您需要在反序列化器中使用 JsonParser 的情况下,您可以尝试以下操作:

JsonLocation start = jp.getCurrentLocation();
jsonParser.getCodec().readTree(jsonParser); // The result is ignored
JsonLocation end = jp.getCurrentLocation();

String xmlText = end.getSourceRef().toString().substring(start.getCharOffset() - 1, end.getCharOffset());

JSONObject jsonObject = XML.toJSONObject(xmlText);
String jsonText = jsonObject.toString();

// Parse jsonText into JsonNode

Or an alternative solution: https://github.com/DinoChiesa/deserialize-xml-arrays-jackson/blob/master/src/main/java/com/google/xmldeser/ArrayInferringUntypedObjectDeserializer.java或替代解决方案: https : //github.com/DinoChiesa/deserialize-xml-arrays-jackson/blob/master/src/main/java/com/google/xmldeser/ArrayInferringUntypedObjectDeserializer.java

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM