Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing a json which contains duplicate keys

Tags:

java

json

jackson

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?

like image 247
Edd Avatar asked Mar 03 '17 07:03

Edd


People also ask

How does JSON handle duplicate keys?

JSON with duplicate key entries have to be handled either by ignoring the duplicate entries or by throwing an exception. Until Mule Runtimes 3.8. 6/3.9. 0, JSON Schema Validator handles them by retaining the last duplicate entry and not throwing an exception.

Can a JSON have duplicate keys?

I've done some research and I understood that "duplicate" keys in JSON are legal, but different parsers act differently in handling this. How can I avoid the use of duplicate keys or, alternatively, make sure the schema validates the value for all duplicated keys? Hermann.

Can JSON have multiple keys with same name?

There is no "error" if you use more than one key with the same name, but in JSON, the last key with the same name is the one that is going to be used. In your case, the key "name" would be better to contain an array as it's value, instead of having a number of keys "name".

What is JSON parse () method?

parse() The JSON. parse() method parses a JSON string, constructing the JavaScript value or object described by the string. An optional reviver function can be provided to perform a transformation on the resulting object before it is returned.


1 Answers

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>
like image 61
Ravi MCA Avatar answered Oct 05 '22 23:10

Ravi MCA