Gson: Gson does not detect duplicate keys in the nested json

Created on 29 May 2015  路  9Comments  路  Source: google/gson

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?

Most helpful comment

Please add a option, which can be set to not allow duplicate keys.

All 9 comments

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);
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

kramer picture kramer  路  26Comments

GoogleCodeExporter picture GoogleCodeExporter  路  15Comments

RobMans426 picture RobMans426  路  20Comments

LucianWang picture LucianWang  路  42Comments

GoogleCodeExporter picture GoogleCodeExporter  路  32Comments