Gson's missing get element function - Part II
The Gson missing recursive get function - Review.
A while back, probably more than a year ago, I wrote an article Gson's Missing recursive get function
where I discussed the shortcomings of the current gson get function, whereby it only traverses top-level entry key for the search key.
In this article I'll introduce a new functionality that allows for even deeper traversal of same name nodes until a primitive value is found (if needed).
where I discussed the shortcomings of the current gson get function, whereby it only traverses top-level entry key for the search key.
In this article I'll introduce a new functionality that allows for even deeper traversal of same name nodes until a primitive value is found (if needed).
{
"result" : {
"total_items" : 1,
"total_pages" : 1,
"items_per_page" : 25,
"current_page" : 1,
"items" : {
"username" : "test",
"items" : {
items: "12345"
},
items: "12345"
},
"secret" : "",
"application" : {
"name" : "test app"
}
}
},
"error" : null,
"id" : 1
}
Above I have given an example whereby the key items is nested (3 items key) . Suppose we wish to search for the items object with the previous recursive get functionality ?
It would be something like this :
import static GsonUtil.*;
// assumption here is that a static import is done. ignoring the GsonUtils for space reasons
get("items", get("item", get("items", response).getAsJsonObject()).getAsJsonObject()).getAsString()
The workaround was to implement a deep traversal mechanism inside the current implementation that would iterate until a primitive type was found.
Refactor:
import java.util.Map.Entry; import java.util.Set; import com.google.gson.JsonElement; import com.google.gson.JsonObject; public class GsonUtil { /** * The following function does a top-down recursive descent on a json tree to * find an element with-in structure * * @param value : value to retrieve * @param jObj : json object to traverse * @return JsonElement if found or null if element not found */ public JsonElement get(String value, JsonObject jObj) { return get(value, jObj, false); } /** * The following function does a top-down recursive descent on a json tree to * find an element with-in structure * * @param value : value to retrieve * @param jObj : json object to traverse * @param deep : determines if object should be traversed further until a primitive is found * @return JsonElement if found or null if element not found */ public JsonElement get(String value, JsonObject jObj, boolean deep) { // check current level for the key before descending if (jObj.isJsonObject() && jObj.has(value)) { if(deep) { if(jObj.isJsonPrimitive() || jObj.get(value).isJsonPrimitive()) return jObj.get(value); return get(value, jObj.get(value).getAsJsonObject(), true); } else return jObj.get(value); } // get all entry sets Set<Entry<String, JsonElement>> entries = jObj.entrySet(); for (Entry<String, JsonElement> entry : entries) { // cache the current value since retrieval is done so much JsonElement curVal = entry.getValue(); if (curVal.isJsonArray()) { for (JsonElement el : curVal.getAsJsonArray()) { // recursively traverse the sub-tree JsonElement res = get(value, el.getAsJsonObject(), deep); if (res != null) return res; } } else if (curVal.isJsonObject()) { // traverse sub-node return get(value, curVal.getAsJsonObject(), deep); } } return (deep) ? jObj : null; } }
Refactor:
import static GsonUtil.*;
// assumption here is that a static import is done. ignoring the GsonUtils for space reasons
get("items", get("item", get("items", response).getAsJsonObject()).getAsJsonObject()).getAsString()
Becomes:
get("items", response, true).getAsString()
The above method solves the short-comings of the previous get method. The above method allows a third parameter to be passed to the function. The third param allows for for further traversal of objects that aren't primitive.
Comments
Post a Comment