To solve the type mismatch problem discussed in this thread , I created custom Deserializers and added them to ObjectMapper . However, performance degrades significantly with this.
With the default deserializer, I get 1-2 garbage collection calls in logcat , while with a custom deserializer there are at least 7-8 GC calls, and therefore the processing time also increases significantly.
My deserializer:
public class Deserializer<T> { public JsonDeserializer<T> getDeserializer(final Class<T> cls) { return new JsonDeserializer<T> (){ @Override public T deserialize(JsonParser jp, DeserializationContext arg1) throws IOException, JsonProcessingException { JsonNode node = jp.readValueAsTree(); if (node.isObject()) { return new ObjectMapper().convertValue(node, cls); } return null; } }; } }
And I use this to add to the mapper
public class DeserializerAttachedMapper<T> { public ObjectMapper getMapperAttachedWith(final Class<T> cls , JsonDeserializer<T> deserializer) { ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(deserializer.toString(), new Version(1, 0, 0, null, null, null)); module.addDeserializer(cls, deserializer); mapper.registerModule(module); return mapper; } }
EDIT: Additional data added
My JSON is significant size, but not huge: I pasted here
Now to parse the same JSON if I use this code:
String response = ConnectionManager.doGet(mAuthType, url, authToken); FLog.d("location object response" + response); // SimpleModule module = new SimpleModule("UserModule", new Version(1, 0, 0, null, null, null)); // JsonDeserializer<User> userDeserializer = new Deserializer<User>().getDeserializer(User.class); // module.addDeserializer(User.class, userDeserializer); ObjectMapper mapper = new ObjectMapper(); // mapper.registerModule(module); JsonNode tree = mapper.readTree(response); Integer code = Integer.parseInt(tree.get("code").asText().trim()); if(Constants.API_RESPONSE_SUCCESS_CODE == code) { ExploreLocationObject locationObject = mapper.convertValue(tree.path("response").get("locationObject"), ExploreLocationObject.class); FLog.d("locationObject" + locationObject); FLog.d("locationObject events" + locationObject.getEvents().size()); return locationObject; } return null;
Then my logcat is like this
But if I use this code for the same JSON
String response = ConnectionManager.doGet(mAuthType, url, authToken); FLog.d("location object response" + response); SimpleModule module = new SimpleModule("UserModule", new Version(1, 0, 0, null, null, null)); JsonDeserializer<User> userDeserializer = new Deserializer<User>().getDeserializer(User.class); module.addDeserializer(User.class, userDeserializer); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(module); JsonNode tree = mapper.readTree(response); Integer code = Integer.parseInt(tree.get("code").asText().trim()); if(Constants.API_RESPONSE_SUCCESS_CODE == code) { ExploreLocationObject locationObject = mapper.convertValue(tree.path("response").get("locationObject"), ExploreLocationObject.class); FLog.d("locationObject" + locationObject); FLog.d("locationObject events" + locationObject.getEvents().size()); return locationObject; } return null;
Then my logcat is like this