Edd
Edd

Reputation: 2032

Parsing a json which contains duplicate keys

I'm trying to parse json with invalid structure which has duplicate keys using Jackson library. If a json has duplicate keys, I would like to extract them as a Collection.

Example of what I'm trying to parse (the actual json that I'm trying to parse comes from Wireshark json export):

{
    "a": "a",
    "a": {
        "b": {

        },
        "b": true
    }
}

However, since this json has duplicate keys, only the last value is retained:

JsonNode tree = new ObjectMapper().readTree(json);
System.out.println(tree); // {"a":{"b":true}}

I've also tried the Guava module which has Multimap support, however it doesn't work as expected for nested json objects.

Example using Guava module for the json that I have shown before:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

Multimap read = mapper.readValue(json, Multimap.class);
System.out.println(read); // {a=[a, {b=true}]}

How should I tackle this problem using Jackson library? Are there any other libraries which would support parsing of such json structure for java?

Upvotes: 9

Views: 13548

Answers (2)

Krzysztof Cichocki
Krzysztof Cichocki

Reputation: 6414

In the Jackson library you can read the JSON message token by token in a streaming way, then it would not eat anything from the message.

Upvotes: 3

Ravi MCA
Ravi MCA

Reputation: 2621

If you are flexible with json library you can make use of net.sf.json.JSONObject.

This library will retain the duplicated values by storing them into arrays. If multiple same keys are available it will create one key with all the values as Array.

And also the coding part is just a single line. Once you parsed the json using net.sf.json.JSONObject then you can supply this to jackson library.

JSONObject jsonObject = JSONObject.fromObject( "{ \"a\": \"a\", \"a\": { \"b\": {},\"b\": true}}" );

System.out.println( "net.sf.json.JSONObject: " + jsonObject );

JsonNode jsonNode = new ObjectMapper().readTree( jsonObject.toString() );

System.out.println( "com.fasterxml.jackson.databind.JsonNode" + jsonNode );

Output:

net.sf.json.JSONObject: {"a":["a",{"b":[{},true]}]}
com.fasterxml.jackson.databind.JsonNode{"a":["a",{"b":[{},true]}]}

Maven dependency of net.sf.json

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>

Upvotes: 9

Related Questions