#1443·gson

JSON Pointer spec (RFC 6901) support

Author: markkolichCreated Dec 11, 2018Updated Aug 26, 2026
Labelsenhancement

Consider the following JSON object:

json
{
  "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:

java
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():

java
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:

java
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.