google / google/gson

JSON Pointer spec (RFC 6901) support

Open
#1,443 13 comments 5 reactions 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
24.2k
Forks
4.5k
Avg merge
6d 4h
Merged PRs (30d)
12

Description

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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.