简体   繁体   English

Java:使用GSON映射的JSON

[英]Java:JSON to map using GSON

I have a string like this 我有这样的字符串

{"key0":"value0","key1":"value1","key0":"value3"}

I want to store it in a map and the desired result is {"key0":"value3","key1":"value1"} 我想将其存储在地图中,所需的结果是{“ key0”:“ value3”,“ key1”:“ value1”}

Using org.json.JsonObject: I passed the string to the constructor and Duplicate key exception is thrown 使用org.json.JsonObject:我将字符串传递给构造函数,并抛出重复键异常

Using GSON: Same exception when I tried through new Gson.fromJson(string,Type) 使用GSON:当我尝试新的Gson.fromJson(string,Type)时,出现相同的异常

Using Jackson: It does work 使用杰克逊:确实有效

Is there a workaround to achieve the same using JSONObject and Gson 是否有使用JSONObject和Gson实现相同目的的解决方法

Interestingly if you first cast that json to an Object and then to a Map<String,String> your desired result happens: 有趣的是,如果您首先将json转换为Object ,然后转换为Map<String,String> ,则会发生所需的结果:

String json = "{\"key0\":\"value0\",\"key1\":\"value1\",\"key0\":\"value3\"}";
Gson gson = new Gson();
Object obj = gson.fromJson(json, Object.class);
try {
    Map<String,String> map = (Map<String, String>)obj;
    // Outputs...
    // key0=value3
    // key1=value1
    for (Map.Entry<String,String> entry : map.entrySet()) {
        System.out.println(entry.getKey() + "=" + entry.getValue());
    }
} catch (ClassCastException e) {
    e.printStackTrace();
}

GSON uses MapTypeAdapterFactory to deserialioze map. GSON使用MapTypeAdapterFactory来反序列化地图。 Below is a short excerpt of its source code where a new entry is put in a map: 以下是其源代码的简短摘录,其中在地图中添加了新条目:

V replaced = map.put(key, value);
if (replaced != null) {
    throw new JsonSyntaxException("duplicate key: " + key);
}

Knowing that there is at least one way to bypass this strict behavior: create your own map that overrides the method put(..) to return always null, like: 知道至少有一种方法可以绕过这种严格的行为:创建自己的映射,该映射将覆盖方法put(..)以始终返回null,例如:

public class DuploMap extends HashMap<String, String>{
    @Override
    public String put(String key, String value) {
        super.put(key, value);
        return null; 
    }
}

then deserailizing to it like: 然后像这样去失败

gson.fromJson(JSON, DuploMap.class);

will not throw that exception. 不会抛出该异常。

You can use GSON's JsonReader if you do not mind the manual effort. 如果您不介意手动操作,则可以使用GSON的JsonReader。

On the plus side: 从积极的一面:

  • faster (no reflection, no casts) 更快(无反射,无投射)
  • fully under your control 完全在您的控制之下

-- -

String json = "{"key0":"value0","key1":"value1","key0":"value3"}";
JsonReader jsonReader = new JsonReader(new StringReader(json));
HashMap<String,String> map = new HashMap<String, String>()
String currKey;
try {
    while(jsonReader.hasNext()){
        JsonToken nextToken = jsonReader.peek();
           if(JsonToken.NAME.equals(nextToken)){
               currKey = jsonReader.nextName();
           }
           if(JsonToken.STRING.equals(nextToken)){
               map.put(currKey, jsonReader.nextString())
           }
    }
} catch (IOException e) {
   e.printStackTrace();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM