Search code examples
javajsonjacksonjackson-databind

Remove JSON node from json object (a json file) in Java


I'm trying to remove few nodes from JSON file. But I'm getting class cast exception when I try to remove node. java.lang.ClassCastException: class com.fasterxml.jackson.databind.node.TextNode cannot be cast to class com.fasterxml.jackson.databind.node.ObjectNode (com.fasterxml.jackson.databind.node.TextNode and com.fasterxml.jackson.databind.node.ObjectNode are in unnamed module of loader 'app')

I tried other stackoverflow useful links, but not working for me. Here is the code that I have written.

public static void removeNodes(String filePath, String... nodeNames) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNodes = objectMapper.readTree(new File(filePath));
        for (JsonNode node : jsonNodes) {
            ((ObjectNode) node).remove(Arrays.asList(nodeNames));
        }
        objectMapper
                .writerWithDefaultPrettyPrinter()
                .writeValue(new File(filePath.split("\\.")[0] + "_modified.json"), jsonNodes);
    }

This is the json file I'm reading.

{
  "boolean_key": "--- true\n",
  "empty_string_translation": "",
  "key_with_description": "Check it out! This key has a description! (At least in some formats)",
  "key_with_line-break": "This translations contains\na line-break.",
  "nested": {
    "deeply": {
      "key": "Wow, this key is nested even deeper."
    },
    "key": "This key is nested inside a namespace."
  },
  "null_translation": null,
  "pluralized_key": {
    "one": "Only one pluralization found.",
    "other": "Wow, you have %s pluralizations!",
    "zero": "You have no pluralization."
  },
  "Dog_key": {
    "nest": "Only one pluralization found.",
    "sample_collection": [
    "first item",
    "second item",
    "third item"
  ],
  "Pest": "Only two pluralization found."
  },
  "simple_key": "Just a simple key with a simple message.",
  "unverified_key": "This translation is not yet verified and waits for it. (In some formats we also export this status)"
}

Caller:

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

// import static org.junit.jupiter.api.Assertions.*;

@RunWith(SpringRunner.class)
@SpringBootTest
class JSONUtilTest {

    @Test
    void removeNodes() throws IOException {
        JSONUtil.removeNodes("D:\\data\\JSON_A.json", "pluralized_key", "Dog_key", "simple_key");
    }
}

Can you help me to figure out what is causing the problem?


Solution

  • As mentioned in the comment, you need to first parse the JSON then do operations on it.

    • Read file.
    • Parse and convert it to JSONObject using JSONParser's parse() method.
    • Remove the nodes you want.

    Using ObjectMapper's writerWithDefaultPrettyPrinter() method you get proper indentation and write that to output file.

    Here is the code:

    public static void removeNodes(String filePath, String... nodeNames) {
       try (FileReader fileReader = new FileReader(filePath)) {
           JSONParser jsonParser = new JSONParser();
           JSONObject jsonObject = (JSONObject) jsonParser.parse(fileReader);
    
           Stream<String> nodeStream = Stream.of(nodeNames);
           nodeStream.forEach(jsonObject::remove);
    
           ObjectMapper objectMapper = new ObjectMapper();
           String jsonObjectPrettified = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
    
           FileWriter fileWriter = new FileWriter(filePath.split("\\.")[0] + "_modified.json");
           fileWriter.write(jsonObjectPrettified);
           fileWriter.close();
    
       } catch (IOException | ParseException e) {
           e.printStackTrace();
       }
    }