Make Gson在使用重复键解析JSON时抛出异常

时间:2014-02-04 15:20:10

标签: java json parsing gson

我正在用Gson解析简单的JSON对象。我希望它在重复密钥名称时抛出一些错误。 E.g。

{
  a: 2,
  a: 3
}

在我的情况下,Gson解析这样的JSON并将a设置为3.我希望它抛出一些异常。

我知道我可以将JSON解析为map,然后Gson会在这种情况下抛出异常,但前提是重复的键没有嵌套在map中。如果我有例如像这样的JSON:

{
  a: 2,
  b: {
    dup: 1,
    dup: 2
  }
}

仍然,它被解析没有任何异常,我只有一个值为2的“dup”。

我可以以某种方式设置Gson在这种情况下抛出错误吗?或者在JsonObject实例中有重复的条目,以便我自己可以检测到它(但我怀疑它,因为它将是无效的JsonObject

可重复的例子

String json = "{\"a\":2, \"a\":3}";
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
System.out.println(jsonObject);

打印出来

{"a":3}

2 个答案:

答案 0 :(得分:4)

1)你可以稍微编辑一下gson的来源。这只是一个了解事情如何运作的建议。我不建议您在真实/生产环境中使用它。

Gson在将json字符串解析为JsonObject时使用com.google.gson.internal.LinkedTreeMap。对于测试问题,您可以使用相同的名称和包名将该类复制到项目中。并编辑其put方法以不允许重复键。

    @Override
    public V put(K key, V value) {
    if (key == null) {
      throw new NullPointerException("key == null");
    }

    // my edit here
    if(find(key, false) != null) {
        throw new IllegalArgumentException("'" + key.toString() + "' is duplicate key for json!");
    }

    Node<K, V> created = find(key, true);
    V result = created.value;
    created.value = value;
    return result;
  }

2)另一个干净的解决方案是定义要映射到json字符串的自定义类。然后编写他们的自定义TypeAdapters

3)使用Deserializer来做?我不认为这是可能的。如果你尝试使用它,你会发现你已经有一个jsonObject,你的重复键被作为一个处理。

答案 1 :(得分:0)

您可以尝试这种方式:

Type mapType = new TypeToken<Map<String, JsonObject>>() {}.getType();

如果json比JsonObject更复杂,则可以用作地图值类型:

{{1}}