Java: JSON для сопоставления с использованием GSON - PullRequest
0 голосов
/ 17 октября 2018

У меня есть такая строка

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

Я хочу сохранить ее на карте, и желаемый результат: {"key0": "value3", "key1": "value1"}

Использование org.json.JsonObject: я передал строку в конструктор и выдается исключение Duplicate key

Использование GSON: то же исключение, когда я пробовал новый Gson.fromJson (string, Type)

Использование Джексона: это работает

Есть ли обходной путь для достижения того же, используя JSONObject и Gson

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Вы можете использовать GSON JsonReader, если не возражаете против ручного труда.

С положительной стороны:

  • быстрее (без отражения, без приведения)
  • полностью под вашим контролем

-

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();
}
0 голосов
/ 18 октября 2018

GSON использует MapTypeAdapterFactory для десериализации карты.Ниже приведена краткая выдержка из ее исходного кода, в которой новая запись помещается в карту:

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

Зная, что существует хотя бы один способ обойти это строгое поведение: создайте собственную карту, которая переопределяет методput(..) для возврата всегда null, например:

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

, затем десертилизация к нему, например:

gson.fromJson(JSON, DuploMap.class);

не сгенерирует это исключение.

0 голосов
/ 17 октября 2018

Интересно, что если вы сначала приведете этот 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();
}
...