you can try
you should modify the file path
ObjectMapper mapper = new ObjectMapper();
ObjectNode nodes = mapper.readValue(new File("D:\\test.txt"),
ObjectNode.class);
nodes.with("addressDetails").put("pinCode", "414141");
mapper.writer().writeValue(new File("D:\\test.txt"), nodes);
Answer from nan lin on Stack Overflowyou can try
you should modify the file path
ObjectMapper mapper = new ObjectMapper();
ObjectNode nodes = mapper.readValue(new File("D:\\test.txt"),
ObjectNode.class);
nodes.with("addressDetails").put("pinCode", "414141");
mapper.writer().writeValue(new File("D:\\test.txt"), nodes);
The problem with your code is that you add your value to a new JsonObject (node), and not the one (root) that you've read in. So basically, you'll have to add it to root. But to be able to do that, you'll have to cast it to an ObjectNode, as JsonNode does not provide any methods to add to the node.
So, try something like the following:
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(new File("D://test.json"));
ObjectNode node = (ObjectNode) root;
node.with("addressDetails").put("pinCode", "414141");
mapper.writer().writeValue(new File("D:\\test.txt"), node);
json - How to modify JsonNode in Java? - Stack Overflow
java - Getting the values of a specific key from JsonNode - Stack Overflow
Give Ability to Replace existing Key with New Key and KEEP SAME ORDER as existing key
json - how to create insert new nodes in JsonNode? - Stack Overflow
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.getValue());
Adding an answer as some others have upvoted in the comments of the accepted answer they are getting this exception when attempting to cast to ObjectNode (myself included):
Exception in thread "main" java.lang.ClassCastException:
com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
The solution is to get the 'parent' node, and perform a put, effectively replacing the entire node, regardless of original node type.
If you need to "modify" the node using the existing value of the node:
getthe value/array of theJsonNode- Perform your modification on that value/array
- Proceed to call
puton the parent.
Code, where the goal is to modify subfield, which is the child node of NodeA and Node1:
JsonNode nodeParent = someNode.get("NodeA")
.get("Node1");
// Manually modify value of 'subfield', can only be done using the parent.
((ObjectNode) nodeParent).put('subfield', "my-new-value-here");
Credits:
I got this inspiration from here, thanks to wassgreen@
You can use elements() method and check if value key exist then add the value to list.
Smaple code
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(data);
List<String> values = new ArrayList<>();
jsonNode.forEach(jsonObject -> jsonObject.elements().forEachRemaining(valueNode -> {
if(valueNode.has("value"))
values.add(valueNode.get("value").asText());
}));
System.out.println(values);
Output:
[http://www.wikidata.org/entity/Q42442324, http://www.wikidata.org/prop/direct/P21, Kiisu Miisu, http://www.wikidata.org/entity/Q43260736, http://www.wikidata.org/prop/direct/P21, Paddles]
Here is the solution by "Josson & Jossons". I list 2 more examples with condition filtering.
https://github.com/octomix/josson
implementation 'com.octomix.josson:josson:1.3.22'
---------------------------------------------
Josson josson = Josson.fromJsonString(
"[" +
" {" +
" \"item\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/entity/Q42442324\"" +
" }," +
" \"prop\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/prop/direct/P21\"" +
" }," +
" \"itemLabel\": {" +
" \"xml:lang\": \"en\", \"type\": \"literal\", \"value\": \"Kiisu Miisu\"" +
" }" +
" }," +
" {" +
" \"item\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/entity/Q43260736\"" +
" }," +
" \"prop\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/prop/direct/P21\"" +
" }," +
" \"itemLabel\": {" +
" \"xml:lang\": \"en\", \"type\": \"literal\", \"value\": \"Paddles\"" +
" }" +
" }" +
"]");
JsonNode node = josson.getNode("*.value");
System.out.println("1.\n" + node.toPrettyString());
node = josson.getNode("~'^item.*'.value");
System.out.println("2.\n" + node.toPrettyString());
node = josson.getNode("*[value.type='uri']*.value");
System.out.println("3.\n" + node.toPrettyString());
Output:
1.
[ "http://www.wikidata.org/entity/Q42442324", "http://www.wikidata.org/prop/direct/P21", "Kiisu Miisu", "http://www.wikidata.org/entity/Q43260736", "http://www.wikidata.org/prop/direct/P21", "Paddles" ]
2.
[ "http://www.wikidata.org/entity/Q42442324", "Kiisu Miisu", "http://www.wikidata.org/entity/Q43260736", "Paddles" ]
3.
[ "http://www.wikidata.org/entity/Q42442324", "http://www.wikidata.org/prop/direct/P21", "http://www.wikidata.org/entity/Q43260736", "http://www.wikidata.org/prop/direct/P21" ]
These methods are in ObjectNode: the division is such that most read operations are included in JsonNode, but mutations in ObjectNode and ArrayNode.
Note that you can just change first line to be:
ObjectNode jNode = mapper.createObjectNode();
// version ObjectMapper has should return ObjectNode type
or
ObjectNode jNode = (ObjectNode) objectCodec.createObjectNode();
// ObjectCodec is in core part, must be of type JsonNode so need cast
I've recently found even more interesting way to create any ValueNode or ContainerNode (Jackson v2.3).
ObjectNode node = JsonNodeFactory.instance.objectNode();