JSON Pointer spec (RFC 6901) support
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.
Source: google/gson