Как использовать динамическое значение JSON в моем классе POJO с Gson?

{
"localeCode": "",
"map": {
    "DynamicName1": [],
    "DynamicName2": [
        {
            "date": "2016-05-15T00:00:00",
            "seqId": 1,
            "status": 10
        },
        {
            "date": "2016-05-16T00:00:00",
            "seqId": 83,
            "status": 10
        }
    ],
    "DynamicName3": [],
    "DynamicName4": []
},
"respCode": 100,
"respMsg": "success",
"status": 1
}

Как правильно отобразить этот вид JSON. Если вы можете видеть это, Dynamic это динамическое имя. Пока я сделал это:

public class MapModel {

public MapObject map;

public static class MapObject{
    public java.util.Map<String, Student> queryStudent;

    public static class Student{
        public String date;
        public String seqId;
        public String status;
    }
}
}

Но когда запустить приложение. я собираюсь NullPointerException, Кто-нибудь может мне помочь?

1 ответ

Вы получаете NullPointerException доступа queryStudent вашей MapObject внутри вашего MapModel поскольку он неправильно заполнен, когда вы пытаетесь десериализовать свой Json.

Итак, чтобы решить вашу проблему, посмотрите документацию Gson, где вы можете увидеть:

Вы можете сериализовать коллекцию с помощью Gson, не делая ничего конкретного: toJson (collection) выдает желаемый результат.

Однако десериализация с помощью fromJson(json, Collection.class) не будет работать, поскольку у Gson нет способа узнать, как сопоставить входные данные с типами. Gson требует, чтобы вы предоставили обобщенную версию типа коллекции в fromJson(). Итак, у вас есть три варианта:

  1. Используйте API синтаксического анализатора Gson (низкоуровневый потоковый анализатор или анализатор DOM JsonParser) для анализа элементов массива, а затем используйте Gson.fromJson() для каждого из элементов массива. Это предпочтительный подход. Вот пример, который демонстрирует, как это сделать.

  2. Зарегистрируйте адаптер типа для Collection.class, который просматривает каждый элемент массива и сопоставляет их с соответствующими объектами. Недостаток этого подхода в том, что он испортит десериализацию других типов коллекций в Gson.

  3. Зарегистрируйте адаптер типа для MyCollectionMemberType и используйте метод fromJson () для Collection.

Так как ваш MapObject содержит java.util.Map но ваш класс сам по себе не является общим, я думаю, что хороший подход для вашего случая заключается в создании Deserializer,

Перед этим попробуйте очистить определение класса, чтобы предоставить конструкторы, облегчающие сборку десериализатора. Ваши классы POJO могут быть:

Студенческий класс

public class Student{
  public String date;
  public String seqId;
  public String status;

  public Student(String date, String seqId, String status){
      this.date = date;
      this.seqId = seqId;
      this.status = status;
  }
}

Класс MapObject

Примечание: я меняю тебя Map определение, так как в вашем Json кажется, что может быть несколько студентов для каждого DynamicName (посмотри на DynamicName2 от твоего вопроса) так что пользуюсь Map<String,List<Student>> вместо Map<String,Student>:

public class MapObject{
   public Map<String,List<Student>> queryStudent;

   public MapObject(Map<String,List<Student>> value){
       this.queryStudent = value;
   }
}

Класс MapModel

public class MapModel {
     public MapObject map;     
}

Теперь создайте Deserializer для тебя MapObject:

public class MapObjectDeserializer implements JsonDeserializer<MapObject> {
  public MapObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {

      Map<String,List<Student>> queryStudents = new HashMap<String,List<Student>>();
      // for each DynamicElement...
      for (Map.Entry<String,JsonElement> entry : json.getAsJsonObject().entrySet()) {

          List<Student> students = new ArrayList<Student>();
          // each dynamicElement has an Array so convert  and add an student
          // for each array entry
          for(JsonElement elem : entry.getValue().getAsJsonArray()){
              students.add(new Gson().fromJson(elem,Student.class));
          }
          // put the dinamic name and student on the map
          queryStudents.put(entry.getKey(),students);
      }
      // finally create the mapObject
      return new MapObject(queryStudents);
  }
}

Наконец зарегистрируйте Deserializer и разбери свой Json:

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(MapObject.class, new MapObjectDeserializer());
Gson gson = builder.create();
MapModel object = gson.fromJson(YourJson,MapModel.class);

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Для быстрого создания прототипов я тестирую это с помощью groovy, я пытаюсь сохранить синтаксис Java, но могу кое-что забыть, в любом случае, я думаю, что это может привести вас в правильном направлении.

Надеюсь, поможет,

Другие вопросы по тегам