How to Modify JSONnode in Java

How to modify JsonNode in Java?

JsonNode is immutable and is intended for parse operation. However, it can be cast into ObjectNode (and ArrayNode) that allow mutations:

((ObjectNode)jsonNode).put("value", "NO");

For an array, you can use:

((ObjectNode)jsonNode).putArray("arrayName").add(object.ge‌​tValue());

Update a value in the nested JsonNode

You can use :

JsonNode data = new ObjectMapper().readTree(dataString);
((ObjectNode) data.get("expiryDate")).put("value", "05-02-2020");

Where :

  • ((ObjectNode) data.get("expiryDate")) you get the parent, and then
  • put("value", "05-02-2020") change the value of the nested node

Output

{"expiryDate":{"type":"String","value":"05-02-2020"}}

Modify JsonNode of unknown JSON dynamically in Java

JsonNode objects are immutable so you can't modify them. What you can do is replace a JsonNode with another one. A cast to ObjectNode is also required to expose the required methods. First find the parent of the node you want to replace :

JsonNode node = root.findParent("JsonPath");

Then use either of these 2 methods to replace it with a new one:

((ObjectNode) node).remove("JsonPath");           // remove current node
((ObjectNode) node).put("JsonPath", "New Value"); // add new one with new value

or

((ObjectNode) node).replace("JsonPath", new TextNode("New Value"));

How to update a certain value inside this jackson JsonNode?

Since my usecase suggests my dependsOn value should not be overridden at node level, I had to convert the JsonNode to String and then used the regular expression matcher to replace :xyz with an empty string in each element then convert it back to JsonNode

String pattern = ":[a-zA-Z]+";
String newDependsOn = dependsOn.toString().replaceAll(pattern, "");
ObjectMapper mapper = new ObjectMapper();
dependsOn = mapper.readTree(newDependsOn);

@Gautham's solution did work too but what I think is it was overriding at the root and the old value wasn't available anymore outside the loop

Java Replace JsonNode with String value

You had just a small problem with your code. When you add the new text entry, you have to provide the key value that you want to associate the new text node with. So this line:

nodeObj.set(newNode);

Just needs to be this:

nodeObj.set("B", newNode);

Here's a complete example that does just what you show in your question, incorporating the code you provided, with just this one small fix:

public static void main(String... args) throws IOException {

// Read in the structure provided from a text file
FileReader f = new FileReader("/tmp/foox.json");
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(f);

// Print the starting structure
System.out.println(rootNode);

// Get the node we want to operate on
ObjectNode jsonNode = (ObjectNode)rootNode.get(0).get("A");

// The OPs code, with just the small change of adding the key value when adding the new String
JsonNode newNode = new TextNode("My String Message");
ObjectNode nodeObj = (ObjectNode) jsonNode;
nodeObj.removeAll();
nodeObj.set("B", newNode);

// Print the resulting structure
System.out.println(rootNode);
}

And the resulting output:

[{"A":{"B":{"C":"Message","D":"FN1"}}}]
[{"A":{"B":"My String Message"}}]

UPDATE: Per the discussion in the comments, to make the change you illustrate, you have to have access to the ObjectNode associated with the key A. It is this ObjectNode that associates B with the ObjectNode containing C and D. Since you want to change the value that B is associated with (you want it to be associated with a TextNode instead of an ObjectNode), you need access to the ObjectNode associated with A. If you only have a pointer to the ObjectNode containing C and D, you can't make the change you want to make.

Update JsonNode with new object values

I have figured out what needs to do. check below code

ObjectMapper mapper = new ObjectMapper();
ObjectNode obj = (ObjectNode) m;
if (seasonsNotesDto!=null)
{
ObjectNode notes = mapper.createObjectNode();
notes.put("notesTitle", seasonsNotesDto.getNotesTitle());
notes.put("notesText", seasonsNotesDto.getNotesText());
notes.put("notesTime", seasonsNotesDto.getNotesTime());
obj.set("notes", notes);
}
return m;

Update value of each item in JsonNode (jackson)

The string textData represents valid json format, so either you can convert it into List<Model> or List<Map<String,String>> using objectmapper

public class Model {
private String acc;
private String foo;

// getters and setters
}

To model List<Model>

List<Model> list = objectMapper.readValue(jsonCarArray, new TypeReference<List<Model>>(){});

or to `List<Map<String,String>>

List<Map<String,String>> list = objectMapper.readValue(jsonCarArray, new TypeReference<List<Map<String,String>>>(){});

And then use computeIfPresent

list.forEach(obj->obj.computeIfPresent("acc",(key,val)-> /*logic to modify value */));

Or another approach by iterating JsonNode

JsonNode response = objectMapper.readTree("responseBody");

if(response.get("data").isArray()) {
for (JsonNode node : response.get("data")){
ObjectNode objectNode = (ObjectNode)node;
if(objectNode.hasNonNull("acc")){
String val = objectNode.get("acc").asText();
objectNode.put("acc","xx"+val.subString(2));
}
}
}

How to modify jackson jsonnode and write pretty json back in scala

Besides using the INDENT_OUTPUT feature Michal suggested, I find an easy way to do pretty print:

val reader = new FileReader("env_config.json")
val mapper = new ObjectMapper()

// need to cast to ObjectNode because JsonNode is immutable
val objectNode = mapper.readTree(reader).asInstanceOf[ObjectNode]

// modify a field
objectNode("service_port", 1234)

// pass a DefaultPrettyPrinter instance to do the pretty print!
val writer = mapper.writer(new DefaultPrettyPrinter());
writer.writeValue(Paths.get("env_config.json").toFile, objectNode)

Cheers!



Related Topics



Leave a reply



Submit