Как использовать динамическое значение 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(). Итак, у вас есть три варианта:
Используйте API синтаксического анализатора Gson (низкоуровневый потоковый анализатор или анализатор DOM JsonParser) для анализа элементов массива, а затем используйте Gson.fromJson() для каждого из элементов массива. Это предпочтительный подход. Вот пример, который демонстрирует, как это сделать.
Зарегистрируйте адаптер типа для Collection.class, который просматривает каждый элемент массива и сопоставляет их с соответствующими объектами. Недостаток этого подхода в том, что он испортит десериализацию других типов коллекций в Gson.
Зарегистрируйте адаптер типа для 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, но могу кое-что забыть, в любом случае, я думаю, что это может привести вас в правильном направлении.
Надеюсь, поможет,