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?
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.
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.
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".
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With