In Jackson, we can use Tree Model to represent the JSON structure, and perform the CRUD operations via JsonNode, similar to the XML DOM tree. This Jackson Tree Model is useful, especially in cases where a JSON structure does not map nicely to Java classes.
pom.xml
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
P.S Tested with Jackson 2.9.8
1. Traversing JSON
1.1 Jackson TreeModel example to traversing below JSON file:
C:\\projects\\user.json
{
"id": 1,
"name": {
"first": "Yong",
"last": "Mook Kim"
},
"contact": [
{
"type": "phone/home",
"ref": "111-111-1234"
},
{
"type": "phone/work",
"ref": "222-222-2222"
}
]
}
1.2 Process JsonNode one by one.
JacksonTreeModelExample1.java
package com.favtuts.json;
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTreeModelExamples {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
traverseJSONprocessJsonNodeOneByOne();
}
static void traverseJSONprocessJsonNodeOneByOne() {
try {
JsonNode root = mapper.readTree(new File("/home/tvt/workspace/favtuts/user.json"));
// Get id
long id = root.path("id").asLong();
System.out.println("id : " + id);
// Get Name
JsonNode nameNode = root.path("name");
if (!nameNode.isMissingNode()) { // if "name" node is exist
System.out.println("firstName : " + nameNode.path("first").asText());
System.out.println("middleName : " + nameNode.path("middle").asText());
System.out.println("lastName : " + nameNode.path("last").asText());
}
// Get Contact
JsonNode contactNode = root.path("contact");
if (contactNode.isArray()) {
System.out.println("Is this node an Array? " + contactNode.isArray());
for (JsonNode node : contactNode) {
String type = node.path("type").asText();
String ref = node.path("ref").asText();
System.out.println("type : " + type);
System.out.println("ref : " + ref);
}
}
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
id : 1
firstName : Yong
middleName :
lastName : Mook Kim
Is this node an Array? true
type : phone/home
ref : 111-111-1234
type : phone/work
ref : 222-222-2222
2. Traversing JSON Array
2.1 JSON file, top level represents an Array.
c:\\projects\\user2.json
[
{
"id": 1,
"name": {
"first": "Yong",
"last": "Mook Kim"
},
"contact": [
{
"type": "phone/home",
"ref": "111-111-1234"
},
{
"type": "phone/work",
"ref": "222-222-2222"
}
]
},
{
"id": 2,
"name": {
"first": "Yong",
"last": "Zi Lap"
},
"contact": [
{
"type": "phone/home",
"ref": "333-333-1234"
},
{
"type": "phone/work",
"ref": "444-444-4444"
}
]
}
]
2.2 The concept is same, just loop the JSON array :
JsonNode rootArray = mapper.readTree(new File("c:\\projects\\user2.json"));
for (JsonNode root : rootArray) {
// get node like the above example 1
}
JacksonTreeModelExample2.java
package com.favtuts.json;
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTreeModelExamples {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
traverseJSONarrayProcessJsonNodeOneByOne();
}
static void traverseJSONarrayProcessJsonNodeOneByOne() {
try {
JsonNode rootArray = mapper.readTree(new File("/home/tvt/workspace/favtuts/user2.json"));
for (JsonNode root : rootArray) {
// Get id
long id = root.path("id").asLong();
System.out.println("id : " + id);
// Get Name
JsonNode nameNode = root.path("name");
if (!nameNode.isMissingNode()) { // if "name" node is exist
System.out.println("firstName : " + nameNode.path("first").asText());
System.out.println("middleName : " + nameNode.path("middle").asText());
System.out.println("lastName : " + nameNode.path("last").asText());
}
// Get Contact
JsonNode contactNode = root.path("contact");
if (contactNode.isArray()) {
System.out.println("Is this node an Array? " + contactNode.isArray());
for (JsonNode node : contactNode) {
String type = node.path("type").asText();
String ref = node.path("ref").asText();
System.out.println("type : " + type);
System.out.println("ref : " + ref);
}
}
}
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
id : 1
firstName : Yong
middleName :
lastName : Mook Kim
Is this node an Array? true
type : phone/home
ref : 111-111-1234
type : phone/work
ref : 222-222-2222
id : 2
firstName : Yong
middleName :
lastName : Zi Lap
Is this node an Array? true
type : phone/home
ref : 333-333-1234
type : phone/work
ref : 444-444-4444
3. Tree model CRUD example
3.1 This example, show you how to create, update and remove JSON nodes, to modify JSON node, we need to convert it to ObjectNode. Read the comments for self-explanatory.
JacksonTreeModelExample3.java
package com.favtuts.json;
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class JacksonTreeModelExamples {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
treeModelCRUDexamples();
}
static void treeModelCRUDexamples() {
try {
JsonNode root = mapper.readTree(new File("/home/tvt/workspace/favtuts/user.json"));
String resultOriginal = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
System.out.println("Before Update " + resultOriginal);
// 1. Update id to 1000
((ObjectNode) root).put("id", 1000L);
// 2. If middle name is empty , update to M
ObjectNode nameNode = (ObjectNode) root.path("name");
if ("".equals(nameNode.path("middle").asText())) {
nameNode.put("middle", "M");
}
// 3. Create a new field in nameNode
nameNode.put("nickname", "favtuts");
// 4. Remove last field in nameNode
nameNode.remove("last");
// 5. Create a new ObjectNode and add to root
ObjectNode positionNode = mapper.createObjectNode();
positionNode.put("name", "Developer");
positionNode.put("years", 10);
((ObjectNode) root).set("position", positionNode);
// 6. Create a new ArrayNode and add to root
ArrayNode gamesNode = mapper.createArrayNode();
ObjectNode game1 = mapper.createObjectNode().objectNode();
game1.put("name", "Fall Out 4");
game1.put("price", 49.9);
ObjectNode game2 = mapper.createObjectNode().objectNode();
game2.put("name", "Dark Soul 3");
game2.put("price", 59.9);
gamesNode.add(game1);
gamesNode.add(game2);
((ObjectNode) root).set("games", gamesNode);
// 7. Append a new Node to ArrayNode
ObjectNode email = mapper.createObjectNode();
email.put("type", "email");
email.put("ref", "abc@tuts.heomi.net");
JsonNode contactNode = root.path("contact");
((ArrayNode) contactNode).add(email);
String resultUpdate = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
System.out.println("After Update " + resultUpdate);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
Before Update {
"id" : 1,
"name" : {
"first" : "Yong",
"last" : "Mook Kim"
},
"contact" : [ {
"type" : "phone/home",
"ref" : "111-111-1234"
}, {
"type" : "phone/work",
"ref" : "222-222-2222"
} ]
}
After Update {
"id" : 1000,
"name" : {
"first" : "Yong",
"middle" : "M",
"nickname" : "favtuts"
},
"contact" : [ {
"type" : "phone/home",
"ref" : "111-111-1234"
}, {
"type" : "phone/work",
"ref" : "222-222-2222"
}, {
"type" : "email",
"ref" : "abc@tuts.heomi.net"
} ],
"position" : {
"name" : "Developer",
"years" : 10
},
"games" : [ {
"name" : "Fall Out 4",
"price" : 49.9
}, {
"name" : "Dark Soul 3",
"price" : 59.9
} ]
}
Download Source Code
$ git clone https://github.com/favtuts/java-core-tutorials-examples
$ cd java-basic/json