Jackson – Tree Model examples
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.mkyong;
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 java.io.File;
import java.io.IOException;
public class JacksonTreeModelExample1 {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
try {
JsonNode root = mapper.readTree(new File("c:\\projects\\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.mkyong;
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 java.io.File;
import java.io.IOException;
public class JacksonTreeModelExample2 {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
try {
JsonNode rootArray = mapper.readTree(new File("c:\\projects\\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.mkyong;
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;
import java.io.File;
import java.io.IOException;
public class JacksonTreeModelExample3 {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) {
try {
JsonNode root = mapper.readTree(new File("c:\\projects\\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", "mkyong");
// 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", "[email protected]");
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" : "mkyong"
},
"contact" : [ {
"type" : "phone/home",
"ref" : "111-111-1234"
}, {
"type" : "phone/work",
"ref" : "222-222-2222"
}, {
"type" : "email",
"ref" : "[email protected]"
} ],
"position" : {
"name" : "Developer",
"years" : 10
},
"games" : [ {
"name" : "Fall Out 4",
"price" : 49.9
}, {
"name" : "Dark Soul 3",
"price" : 59.9
} ]
}
How to update the Contact array.
For Ex: Change :
“contact” : [ {
“type” : “phone/home”,
“ref” : “111-111-1234”
}
to:
“contact” : [ {
“type” : “phone/home”,
“ref” : “000-111-1234”
}
Hi, I m regular reader, and its very helpful website. I have a query on Jackson JSON string to Object conversion. Everything works perfectly fine except the following. JSON string is having a node like “urn:ietf:params:scim:schemas:extension:enterprise:2.0:User”.
How can I map it into a Java class?
Code snippet:
Sample JSON:
{
“schemas”: [ “urn:ietf:params:scim:schemas:core:2.0:User”, “urn:ietf:params:scim:schemas:extension:enterprise:2.0:User”],
“name”: {
“formatted”: “Ms. Barbara J Jensen III”,
“familyName”: “Jensen”,
“givenName”: “Barbara”,
“middleName”: “Jane”,
“honorificPrefix”: “Ms.”,
“honorificSuffix”: “III”
},
“emails”: [
{
“value”: “[email protected]”,
“type”: “work”,
“primary”: true
},
{
“value”: “[email protected]”,
“type”: “home”
}
],
“id”: “2819c223-7f76-453a-919d-413861904646”,
“externalId”: “701984”,
“urn:ietf:params:scim:schemas:extension:enterprise:2.0:User”: {
“employeeNumber”: “701984”,
“costCenter”: “4130”,
“organization”: “Universal Studios”,
“division”: “Theme Park”,
“department”: “Tour Operations”,
“manager”: {
“value”: “26118915-6090-4610-87e4-49d8ca9f808d”,
“$ref”: “../Users/26118915-6090-4610-87e4-49d8ca9f808d”,
“displayName”: “John Smith”
}
}
}
SCIMUser scimUser = mapper.readValue(jsondata, SCIMUser.class);
public class SCIMUser {
private List schemas;
private Map name;
private List<Map> emails;
private String id;
private String externalId;
// what to do with “urn:ietf:params:scim:schemas:extension:enterprise:2.0:User” ?
… then I have all setters-getters here …
}
I hope you got my question. Kindly suggest.
Regards,
Nik
do we have to rewrite whole root, while doing little CRUD operations?
it was very usefully!!
Why not just use ObjectNode as the root node in “3. TreeModel CRUD Example”? It would avoid all the casts no?
I have two class:
class A {
int id;
String name;
}
class B {
String property1;
String property2;
String property3;
}
– A extends B
– Response:
{
“property1”: “value1”,
“property2”: “value2”,
“property3”: “value3”
“id”:1,
“name”: ‘my name”
}
I want to display as below
{
id:1,
“name”: ‘my name’,
“property1”: “value1”,
“property2”: “value2”,
“property3”: “value3”
}
How to do that?
Thank All!
Hi, How will this work if I do not know the keyName (keys) or the size (level of nesting) of the JSON. Can we dynamically get the keys first and then the values? (I need to collect the key and values in an XL for further processing)
Is there a way to traverse and drop the element from nested JSON?
Make some thing with object []
Article is updated to Jackson 2.6.3, with a lot new examples. Refer to example 2 . Just loop the nodes.
how to change the “name”
“name” : “updated name”
change “name” to “myname”
Refer to example 3, how to create or update a JsonNode
thank you this is very useful!, but I still need help 🙁
the jason file i need to modify is like this:
{
“profiles”: {
“AmiliousPixelmon”: {
“authentication”: {
“username”: “X_Amilious_X”,
“accessToken”: “ad15f3240baf4a31b447d2f045358855”,
“uuid”: “c08641daa63c4da485e7ba67f3688185”,
“displayName”: “X_Amilious_X”
},
“name”: “AmiliousPixelmon”,
“gameDir”: “C:\\Users\\School\\AppData\\Roaming\\.minecraft”,
“lastVersionId”: “AmiliousPixelmon”
},
“New Profile”: {
“name”: “New Profile”,
“gameDir”: “C:\\Users\\School\\AppData\\Roaming\\.minecraft”,
“lastVersionId”: “AmiliousPixelmon”,
“allowedReleaseTypes”: [
“snapshot”,
“release”
]
},
“New Profile?”: {
“name”: “New Profile?”,
“gameDir”: “C:\\Users\\School\\AppData\\Roaming\\.minecraft”,
“lastVersionId”: “AmiliousPixelmon1.5.2”,
“allowedReleaseTypes”: [
“release”,
“snapshot”
]
},
“(Default)”: {
“authentication”: {
“username”: “X_Amilious_X”,
“accessToken”: “e719148cdbeb4545ae53a87eb79f1027”,
“uuid”: “c08641daa63c4da485e7ba67f3688185”,
“displayName”: “X_Amilious_X”
},
“name”: “(Default)”
}
},
“selectedProfile”: “New Profile”,
“clientToken”: “0b02dff0-834e-4c08-b469-e13bb2832597”
}
and what I want to do is read all the info into a multidimensional array check if a profile exists and if it does not create it. Can you help me????
Refer to example 3 above – TreeModel CRUD Example
Hey Brandon, Did you figure it out how to do this.
Very useful! Thank you!
Welcome. Article is fully updated to Jackson 2.6.3