Albert Lacambra BasilAlbert Lacambra Basil

Since Java API for JSON Processing (JSR 374) version 1.1, it is possible to use JosnPointer.

JsonPointer is a specification of rfc6901 and as we can read on it, JSON Pointer defines a string syntax for identifying a specific value within a JavaScript Object Notation (JSON) document. In other words, it is possible now to evaluate and change values from our JsonObjects using a pointer string instead to go through the whole chain of calls and recreating an object builder at the end.

So instead of that:

String nameWithObject = jsonObject.getJsonArray("user_mentions").getJsonObject(0).getString("name");

we can do that:

String nameWithPointer = ((JsonString)Json.createPointer("/user_mentions/

We can easily see, that the use of pointers make easier to know which element we are fetching and more intuitive to write. However, since the pointer is returning a JsonValue, we need to use a cast to be able to fetch the final value.

Why JsonPointer is not providing methods to directly get java types like JsonObject is doing, is something I do not really know.

So, what can we do with the JSON pointer?

We can not only get values from a JsonStructure using pointer notation but also modify the object without the need to reconvert it into its builder equivalent. So specifically we can:

  • add a value to a JsonStructure

  • check if a value is contained into a JsonStructure

  • remove a value from a jsonStructure

  • replace a value into a JsonStructre

Let’s see some examples. For the examples, I will use the the following json object:

{
    "id":1,
    "user":{
        "name":"some-name",
        "lastname":"some-lastname"
    },
    "user_mentions":[
        {
            "name":"Twitter API",
            "indices":[
                4,
                15
            ],
            "screen_name":"twitterapi",
            "id":6253282,
            "id_str":"6253282"
        }
    ]
}
Get a simple value from an object:
JsonNumber id = ((JsonNumber) Json.createPointer("/id").getValue(example));
Get an object from an object.
JsonObject user = Json.createPointer("/user").getValue(example).asJsonObject();
get an array from an object
JsonArray userMentions = Json.createPointer("/user_mentions").getValue(example).asJsonArray();
get an element from an array
JsonObject mention = Json.createPointer("/user_mentions/0").getValue(example).asJsonObject();
String mentionName = ((JsonString) Json.createPointer("/user_mentions/0/name").getValue(example)).getString();
int mentionIndex0 = ((JsonNumber) Json.createPointer("/user_mentions/0/indices/1").getValue(example)).intValue();
check if an object contains an element
Assertions.assertTrue(Json.createPointer("/id").containsValue(example));
Assertions.assertTrue(Json.createPointer("/user_mentions/0/indices/0").containsValue(example));
Assertions.assertTrue(Json.createPointer("/user_mentions/0/indices/1").containsValue(example));
Assertions.assertFalse(Json.createPointer("/user_mentions/0/indices/2").containsValue(example));
Add a simple value
JsonObject extendedExample = Json.createPointer("/timestamp").add(example, Json.createValue(System.currentTimeMillis()));
Assertions.assertTrue(Json.createPointer("/timestamp").containsValue(extendedExample));
Add an element to a JsonArray. The pointer must point to the last_element + 1 index. Empty elements would produce an error.
extendedExample = Json.createPointer("/user_mentions/0/indices/2").add(extendedExample, Json.createValue(30));
Assertions.assertEquals(30, ((JsonNumber) Json.createPointer("/user_mentions/0/indices/2").getValue(extendedExample)).intValue());
Replace elements
example = Json.createPointer("/id").replace(example, Json.createValue(2));
Assertions.assertEquals(2, example.getInt("id"));
example = Json.createPointer("/user_mentions/0/indices/1").replace(example, Json.createValue(9999));
Assertions.assertEquals(9999, ((JsonNumber) Json.createPointer("/user_mentions/0/indices/1").getValue(example)).intValue());
Remove elements
example = Json.createPointer("/id").remove(example);
Assertions.assertFalse(example.containsKey("id"));

Source code on github