Gson is unable detect duplicate keys in the nested json
See below code snippet
public static void main(String[] args) throws IOException {
Map<String, ?> map;
//this does not detect duplicate 'key'
map = new Gson().fromJson("{'a':'x','aa':{'key':'x','key':'y'}}", Map.class);
//As expected , this call fails with Exception in thread "main" com.google.gson.JsonSyntaxException: duplicate key: a
map = new Gson().fromJson("{'a':'x','a':'y'}", Map.class);
}
Is this the expected behavior ?
If so is there any alternative to fail in the first case as well?
At the moment, this is the expected behavior. What would you like the behavior to be.
Looks like MapTypeAdapterFactory checks for duplicate
V replaced = map.put(key, value);
if (replaced != null) {
throw new JsonSyntaxException("duplicate key: " + key);
}
however ObjectTypeAdapter does not
case BEGIN_OBJECT:
Map<String, Object> map = new LinkedTreeMap<String, Object>();
in.beginObject();
while (in.hasNext()) {
map.put(in.nextName(), read(in));
}
in.endObject();
return map;
Yes, we could change it to allow duplicates, and let the last JSON value override previous values.
@swankjesse Why did we disallow duplicates? I propose that we change this behavior to allow duplicates with the last value overriding previous values. This is same behavior as JsonObject.
@JakeWharton @joel-leitch
@inder123 I think this should be consistent .
It would be nice to have a flag (say allowDuplicateKey) in GsonBuilder to toggle this option.
allowDuplicateKey should be true by default to follow json Spec.
but User can turn it off , if parsing needs to be more restrictive.
Added a pull request to fix this:
https://github.com/google/gson/pull/649
Please add a option, which can be set to not allow duplicate keys.
+1 for the option
Try this: extend the Map and override the "put" method
public class MyMap<A,B> extends TreeMap<A,B> {
@Override
public B put(A key, B value) {
if (containsKey(key)) {
//TODO : Replace, discard...do whatever you want
}
return super.put(key, value);
}
}
public static void main(String[] args) throws IOException {
MyMap<String, ?> map;
//this does not detect duplicate 'key'
map = new Gson().fromJson("{'a':'x','aa':{'key':'x','key':'y'}}", MyMap.class);
//As expected , this call fails with Exception in thread "main" com.google.gson.JsonSyntaxException: duplicate key: a
map = new Gson().fromJson("{'a':'x','a':'y'}", MyMap.class);
}
Most helpful comment
Please add a option, which can be set to not allow duplicate keys.