1
{
"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
}

How to correctly map this kind of json. If you can see that, Dynamic is a dynamic name. So far I have done this :

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;
    }
}
}

But when run the app. I'm getting NullPointerException. Can somebody help me?

Community
  • 1
  • 1
Azizi Musa
  • 1,009
  • 2
  • 10
  • 31
  • check this answer, it shows how to get the keys in an object, i think you have to do it manually , to get all keys in "map" and iterate over http://stackoverflow.com/questions/31094305/java-gson-getting-the-list-of-all-keys-under-a-jsonobject – Yazan May 18 '16 at 07:54

1 Answers1

3

You're getting the NullPointerException accessing queryStudent of your MapObject inside your MapModel since it's not correctly filled when you're trying to deserialize your Json.

So to solve your problem look at Gson documentation where you can see:

You can serialize the collection with Gson without doing anything specific: toJson(collection) would write out the desired output.

However, deserialization with fromJson(json, Collection.class) will not work since Gson has no way of knowing how to map the input to the types. Gson requires that you provide a genericised version of collection type in fromJson(). So, you have three options:

  1. Use Gson's parser API (low-level streaming parser or the DOM parser JsonParser) to parse the array elements and then use Gson.fromJson() on each of the array elements.This is the preferred approach. Here is an example that demonstrates how to do this.

  2. Register a type adapter for Collection.class that looks at each of the array members and maps them to appropriate objects. The disadvantage of this approach is that it will screw up deserialization of other collection types in Gson.

  3. Register a type adapter for MyCollectionMemberType and use fromJson() with Collection.

Since your MapObject containts a java.util.Map but your class itself it's not generic, I think that a good approach for your case is create a Deserializer.

Before this try to clean up your class definition, to provide constructors to make the deserializer easy to build. Your POJO classes could be:

Student class

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 class

Note: I change you Map definition, since in your Json seems that could be multiple students for each DynamicName (look at DynamicName2 from your question), so I use Map<String,List<Student>> instead of Map<String,Student>:

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

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

MapModel class

public class MapModel {
     public MapObject map;     
}

Now create a Deserializer for your 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);
  }
}

Finally register the Deserializer and parse your Json:

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

DISCLAIMER: For fast prototyping I test this using groovy, I try to keep the Java syntax but I can forget something, anyway I think that this can put you on the right direction.

Hope it helps,

albciff
  • 18,112
  • 4
  • 64
  • 89