Consider the following JSON object:
{
"foo": {
"bar": {
"baz": "bat"
}
}
}
Using GSON, without registering a custom type adapter, if I want to safely access member foo.bar.baz I end up with something like this:
final JsonObject object = new GsonBuilder().create().fromJson("{...}", JsonObject.class);
final JsonObject foo = object.getAsJsonObject("foo");
if (foo != null) {
final JsonObject bar = foo.getAsJsonObject("bar");
if (bar != null) {
final JsonElement baz = bar.get("baz");
if (baz != null && baz.isJsonPrimitive()) {
final String bat = baz.getAsString();
// ...
}
}
}
Instead, I'd love to be able to call a single method on the initial JsonObject itself, something like getStringAtPath():
final JsonObject object = new GsonBuilder().create().fromJson("{...}", JsonObject.class);
final String baz = object.getStringAtPath("foo.bar.baz"); // <<-- !!
if (baz == null) {
// ... didn't exist.
}
In lieu of this missing API, I cooked up a simple helper method for String primitives:
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
@Nullable
public static final String getStringAtPath(
final JsonObject object,
final String path) {
Preconditions.checkNotNull(object, "JSON object cannot be null.");
Preconditions.checkNotNull(path, "JSON object path cannot be null.");
JsonObject base = object;
final Iterable<String> segments = Splitter.on(".").split(path);
for (final String segment : segments) {
final JsonElement element = base.get(segment);
if (element == null) {
return null;
}
if (element.isJsonPrimitive()) {
final JsonPrimitive primitive = element.getAsJsonPrimitive();
return primitive.getAsString();
} else if (element.isJsonObject()) {
base = element.getAsJsonObject();
} else {
return null;
}
}
return null;
}
It would be tremendously helpful if similar methods were conveniently folded into the JsonObject API itself. It could easily be extended for the other types as well: int, boolean, char, double, etc. Admittedly, things get a bit hairy with arrays but I'd imagine support for paths like foo.bar[8].baz could work.
Apologies if this is a dupe, I did briefly search the existing set of issues but didn't immediately find anything related.
Consider the following JSON object:
{ "foo": { "bar": { "baz": "bat" } } }Using GSON, without registering a custom type adapter, if I want to safely access member
foo.bar.bazI end up with something like this:Instead, I'd love to be able to call a single method on the initial
JsonObjectitself, something likegetStringAtPath():In lieu of this missing API, I cooked up a simple helper method for String primitives:
It would be tremendously helpful if similar methods were conveniently folded into the
JsonObjectAPI itself. It could easily be extended for the other types as well: int, boolean, char, double, etc. Admittedly, things get a bit hairy with arrays but I'd imagine support for paths likefoo.bar[8].bazcould work.Apologies if this is a dupe, I did briefly search the existing set of issues but didn't immediately find anything related.