Manipulating Nested JSON Values in Java Using the org.json Library

Omar De Los Santos
Sep 3, 2018 · 4 min read

The org.json library provides a convenient way to convert Java Strings to JSON and back (with many methods in between to get and set values). Unfortunately, it doesn’t appear to include a method that easily helps you get and set nested values (something like Clojure’s get-in function).

Luckily, this can be accomplished fairly painlessly with recursion. Let’s represent the dolls above with JSON. That’d look like this:

If we want to change the value of "green doll" to "Dolly", we’ll need to follow a few steps. First, we’ll need to convert the JSON String to a JSONObject. Simply passing in the String to the JSONObject constructor will accomplish that as long as the String is properly formatted (including escaping double quotes with /.

Parsing the Path

First, we’ll need to parse our way into the nested value. The JSON Pointer format provides an intuitive way to reference the nested key whose value you’d like to manipulate. A String containing the path of keys — separated by / like the one below points to "the littlest doll!" .

"/black doll/red doll/blue doll/green doll" 

To get each individual key, we can split the String based on the leading slash before each key. Since the split method includes an empty leading substring when there is a positive-width match at the beginning of this string, we’ll ensure that the String contains a leading slash, but we’ll remove that leading slash when we split the String.

Getting the Value

Supposing we don’t know the name of the most nested doll, we’ll have to get into the the value belonging to the most nested key. To do so, our recursive function will need to contain two base cases:

  1. If we make it down to the last key, and the current key/value pair we’re looking at contains the value.
  2. Somewhere along the line of keys leading to the desired value, one of the keys doesn’t exist.

For the latter case, you can choose to return whatever you’d like depending on your implementation. Because I’m applying JSON Patch changes in an HTTP server, the UnprocessableEntityException signals to the calling class that the change (in this case just accessing the desired value) did not occur successfully, and it can catch the exception with the appropriate response. You can just as easily return null or any value that suits your implementation.

If neither of the base cases was met, that means that the key in the path matches a key/value pair in the current JSONObject. We’ll need to move into the nested JSONObject by updating jsonObject and keys before recursively calling the function. To get the nestedJsonObjectVal, we’ll need to get the nested JSONObject using the using the intuitively named getJSONObject method. Note that this method will throw a JSONException if the value is not a JSONObject(e.g. the value is a String). Again, you can catch or throw that exception however you see fit.

When we move into the next nested JSONObject, we’ll need to update our keys array. Otherwise, we’ll be looking for the first key inside of the nested JSONObect (which may or may not exist). We can get rid of the first key by taking a copy of the keys array starting with the index of the next key.

Together, the code will look like this:

If we’re happy with the name, we can stop there. If not, we can move on to changing it.

Adding a Value

Adding a value requires altering the return type (JSONObject instead of String), the first base case, and the recursive call. The IETF specifies that JSON Patch documents will add a key/value pair if the target does not exist, but it will replace an existing value if they target does exist (RFC 6902). For that reason, we no longer check to ensure that the JSON object that the last key in keys references contains the final key. The second base case ensures that we only make it this far if every other key in keys pointed to existing values. The put method works cleanly since it adds a key/value pair if it does not already exist, but it replaces the value if the key does exist.

Since this function returns a JSONObject, our recursive call will also need to do the same. Since we’ll eventually be updating a value inside, we’ll use the put method again after updating the JSONObject and keys.

Assuming that you’ve created created a JSONObject instance from a JSON String and set it to a variable named jsonObject, a call to change the name would look like:

String newName = "Dolly";
String path = "/black doll/red doll/blue doll/green doll";
String[] keys = extractKeys(path);
jsonObect = addValue(newName, jsonObject, keys);

Removing a Value

If we’d rather remove the innermost doll entirely, we can do so with code that looks very similar to the two methods above. However, our first base case does have to ensure that the current key exists. Do note that the remove method returns null if the key didn’t exist, so that could cause some nasty bugs/errors if you wanted to make use of that value without checking that the key exists. We return the entire jsonObect after we’ve removed the key so that the JSONObject above receives the updated nested JSONObject as its value.


There are some limitations to these methods. They currently only support getting and setting String values. Additionally, this implementation does not permit replacing the entire JSONBody with another JSONBody. However, you should be able to use the same recursive logic to accomplish that if you need it.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade