Search code examples
javajacksonjsonparser

Using jackson to insert and remove inner nodes in a JSON?


I have a complex json, and a list of keys, which represent an arbitrary long "path" to a specific node I would like to access, remove or insert.
Is that possible?
e.g for the json

{
  "token": {
    "d1": 3000,
    "d2": [
      {
        "d3": "a1",
        "d4": "a2"
      }
    ],
    "d5": [
      "d6",
      "d7"
    ],

  "d8": {
    "d9": true,
    "d10": 10000
  }
}

and the list

['token','d2','d3']

for an insert command, the result of

removeFromJson(jsonString,key_path)

Would be

{
  "token": {
    "d1": 3000,
    "d2": [
      {
        "d4": "a2"
      }
    ],
    "d5": [
      "d6",
      "d7"
    ],

  "d8": {
    "d9": true,
    "d10": 10000
  }
}

Solution

  • I'd lean on JsonNode and, as Thomas mentioned in the comments, its get and remove methods. Something like:

    public void remove(String json, List<String> path) {
    
        JsonNode root = new ObjectMapper.readTree(json);
    
        int lastIndex = path.size() - 1;
    
        for (int i = 0; i < lastIndex; i++) {
            root = root.get(path.get(i));
        }
    
        root = root.remove(path.get(lastIndex));
    
        return root;
    }
    

    You could optimize iteration further with a sublist or a stream, and you'll probably want to handle cases in which your path doesn't actually lead to anything within the given json.

    Note: This option works if you need this behavior on an arbitrary path within an arbitrary object - JsonNode is good for exactly the case in which you don't know what you'll be getting. If you do know what you'll be getting (it's always the same thing being removed from the same object), it's probably better form to just deserialize your JSON into an object using a mapper set to ignore fields missing in the object but present in the JSON.