Преобразование строки JSON в сопоставление с пользовательскими типами

#java #json #jackson

#java #json #джексон

Вопрос:

Моя строка JSON выглядит следующим образом:

 {
    "100": {
        "mode": 100,
        "enabled": true,
        "value": "someString"
    },
    "101": {
        "mode": 101,
        "enabled": false,
        "value": "someString"
    }
}
  

На самом деле у меня есть класс

 class Mode {

    @JsonProperty("mode")
    long mode;

    @JsonProperty("enabled")
    boolean enabled;

    @JsonProperty("value")
    String value;

}
  

Я пытался

 objectMapper.readValue(jsonString, Map.class); 
  

Но его общая карта, а также числа преобразуются в Integer типы not Long . Использование Mode вместо Map вышеуказанного вызывает исключение.

  1. Как попасть Long в generic Map ?
  2. И как я могу получить a Map<String, Mode> из строки json?

У меня есть библиотека jackson в моих проектах maven.

Ответ №1:

ваш ключ String . Это будет работать для вас.

 TypeReference<HashMap<String, Mode>> typeRef = new TypeReference<HashMap<String, Mode>>() {};
Map<String,Mode> map = objectMapper.readValue(jsonString,typeRef);
  

Обновлено :

 import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Mode {

  @JsonProperty("mode")
  long mode;

  @JsonProperty("enabled")
  boolean enabled;

  @JsonProperty("value")
  String value;

  @Override
  public String toString() {
    return "Mode{"  
        "mode="   mode  
        ", enabled="   enabled  
        ", value='"   value   '''  
        '}';
  }

  public static void main(String[] args) throws IOException {
    String json = "{n"
          "    "100": {n"
          "        "mode": 100,n"
          "        "enabled": true,n"
          "        "value": "someString"n"
          "    },n"
          "    "101": {n"
          "        "mode": 101,n"
          "        "enabled": false,n"
          "        "value": "someString"n"
          "    }n"
          "}";

    ObjectMapper objectMapper = new ObjectMapper();
    TypeReference<HashMap<String, Mode>> typeRef = new TypeReference<HashMap<String, Mode>>() {
    };
    Map<String, Mode> map = objectMapper.readValue(json, typeRef);
    map.entrySet().forEach(entry-> System.out.println(entry.getKey()   " : "  entry.getValue() ));
  }
}
  

Вывод :

 100 : Mode{mode=100, enabled=true, value='someString'}
101 : Mode{mode=101, enabled=false, value='someString'}
  

Комментарии:

1. com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of "com.xyz.Mode" (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)"{"1001":{"mode":9223372036854775807,"enabled":true,"value":8}}"; line: 1, column: 10] (through reference chain: java.util.LinkedHashMap["1001"])

2. Спасибо, Халид, что посмотрел. Как я уже сказал, я получаю исключение выше.

3. @xploreraj смотрите обновленный код. Это работает отлично. и я также показываю результат после чтения Json.

4. Спасибо, Халид. Я создавал карту, а затем использовал typeref, вот почему я думаю, что получил ошибку. Ваши решения работают. Что касается целого числа в Long, я выяснил, что если number выходит за пределы диапазона для int, он автоматически преобразуется Джексоном в Long .