如何使用Gson在我的POJO类上使用动态json值?

时间:2016-05-17 04:10:41

标签: java android pojo jsonschema2pojo 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 个答案:

答案 0 :(得分:1)

NullPointerExceptionqueryStudent MapObject访问MapModel MapObject,因为您的java.util.Map未正确填写Deserializer试图反序列化你的 Json

为了解决您的问题,请查看Gson documentation,您可以看到:

  

您可以使用Gson序列化集合而无需执行任何操作   具体:toJson(集合)会写出所需的输出。

     

然而,使用fromJson(json,Collection.class)进行反序列化将会   因为Gson无法知道如何将输入映射到   类型。 Gson要求您提供通用版本   fromJson()中的集合类型。所以,你有三个选择:

     
      
  1. 使用Gson的解析器API(低级流解析器或DOM解析器)   JsonParser)解析数组元素然后使用Gson.fromJson()   在每个数组元素上。这是首选方法。这是   一个演示如何执行此操作的示例。

  2.   
  3. 为Collection.class注册一个类型适配器,查看每个类型   数组成员并将它们映射到适当的对象。缺点   这种方法的方法是它会搞砸其他的反序列化   Gson中的集合类型。

  4.   
  5. 为MyCollectionMemberType注册一个类型适配器并使用fromJson()   收集。

  6.   

由于您的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; } } 包含Map,但您的班级本身并不是通用的,我认为对您的案例来说,一个好的方法是创建一个DynamicName

在此之前尝试清理类定义,提供构造函数以使反序列化器易于构建。您的 POJO 类可以是:

学生班

DynamicName2

MapObject类

注意:我更改了您Map<String,List<Student>>的定义,因为在您的 Json 中似乎可能是每个Map<String,Student>的多个学生(从您的问题中查看public class MapObject{ public Map<String,List<Student>> queryStudent; public MapObject(Map<String,List<Student>> value){ this.queryStudent = value; } } ),所以我使用public class MapModel { public MapObject map; } 代替Deserializer

MapObject

MapModel类

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

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

最后注册{{1}}并解析 Json

{{1}}

免责声明:对于快速原型设计我使用 groovy 进行测试,我尝试保留 Java 语法,但我可以忘记一些东西,无论如何我认为这可以让你正确的方向。

希望它有所帮助,