Mapping Complex data to customized gson Handlers


(Samuel Male) #1

Hi folks,

I’m trying to Serialize and Deserialize a Collection of data. But I’m still stuck on how to implement the handlers.

public interface Resource {
// Some logic goes here
} 

public class Patient implements Resource {
//Patient Resource logic
}

public class Location implements Resource {
//Location Resource logic
}

@Test
public void dummyTest() {
List<Patient> patients = getPatients();
List<Location> locations = getLocations();

//Add the Resources to a Collection
HashMap<String, List<Resource>> resourceMap = new HashMap<String, List<Resource>>();
resourceMap.add("Patient", patients);
resourceMap.add("Location", locations);

//Serialize
String data = gson.toJson(resourceMap); // Works fine

//deserialize
HashMap deserializedObj = gson.fromJson(data, HashMap.class);

//Attempt getting a Patient object.
List<Resource> patientResources = deserializedObj.get("Patient");

for (Resource pat : patientResources) {
      Patient patient = (Patient) pat; //Ooopppss, this throws an Exception."ClassCastException : gson.internal.LinkedTreeMap cannot be cast to Patient.class"
}

} 

So I realized I had to implement my own customized Deserialization Handler. So I cameup with a ResourceDeserialization Handler.

public class ResourceDeserializer implements JsonDeserializer<Resource> {

@Override
public Resource deserialize(JsonElement json, Type type, JsonDeserializationContext context)
		throws JsonParseException {
	JsonObject jsonObject = json.getAsJsonObject();
	if (jsonObject != null) {
		return context.deserialize(jsonObject, getClassInstance(jsonObject.getAsString()));
	}
	return null;
}

private Class getClassInstance(String className) {
	try {
		return (Class)Class.forName(className);
	} catch (ClassNotFoundException e) {
		throw new JsonParseException(e.getMessage());
	}
 }

}

Now the challenge I face is here! Whats really next?

public HashMap<String, List<Resource>> deserialize(String json) {
	Gson gson = new GsonBuilder().registerTypeAdapter(Resource.class, new ResourceDeserializer()).create();

	// How can I do the actual Deserialization . This has blocked me a while.
    /**
      gson.fromJson(json, 'What goes here?');
    */

	
}

This has blocked me from completing the importing part of the module. Could someone help me here.

cc: @ssmusoke, @dkayiwa , @mksd


(Samuel Male) #2

Any goodies for me devs :wink:

cc: @ssmusoke , @dkayiwa


(Daniel Kayiwa) #3

Can you be more detailed? What is the use case?


(Samuel Male) #4

Its for exporting and importing Patient data. So I had planned to store the data in a Map<String, Resource> . Is there a better implementation?

So I’m planning to serialize the Map with data. The challenge is with deserialization. Actually casting a Resource to its type to be more specific.

Around. I tried to implement a deserialization handler but I need guidance here.

Btw, I made a mistake up there which am gonna edit. The Map looks like

Map<String, ArrayList<Resource>> store;

where we could add data like

List<Patient>  patients = new ArrayList<Patient>();
List<Location> locations = new ArrayList<Location>();

// TODO :- Add some data to the lists.

HashMap<String, Resource> store = getStore();

//Add patient data to be serialized.
store.add("Patient", patients);
store.add("Location", locations);

//Serialize
String json = gson.toJson(store);

//Deserialize
HashMap<String,  ArrayList<Resource>> deserializedData = gson.fromJson(json, HashMap<String, ArrayList<Resource>>);

//Try to retrieve Patient data.
List<Resource> patients = deserializedData.get("Patient");
for(Resource pat : patients) {
     Patient patient = (Patient)pat;//Ooooppsss, throws ClassCastException : gson.internal.LinkedTreeMap cannot be cast to Patient.class

}

Now I realised I had to implement a deserialization Handler. Thats were I need yr help.

The above code my have typos. I have been just typing it from here just quickly


(Samuel Male) #5

I thought of using this implementation if I’m still blocked with the above.

public class Store {
    List<Patient> patients;
    List<Location> locations;
 
    //Setters and getters
}

And I will serialize the Store object.


(Stephen Senkomago Musoke) #6

@samuel34 How will you do this for a site with 10,000 patients? Won’t you run into memory issues?


(Samuel Male) #7

@ssmusoke so whats the best way to implement this?