1
0

Part 6: tree navigation, path() vs get(), treeToValue

This commit is contained in:
2026-08-04 17:33:37 +00:00
parent 6e6f6c48ff
commit 2ca907d245

View File

@@ -0,0 +1,50 @@
package com.ankurm.jackson3.part6streaming;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.json.JsonMapper;
/**
* Post: Streaming API and JsonNode — https://ankurm.com/jackson-streaming-api-jsonnode/
* Sections: "The Tree Model" and "Mixing Tree Model with Data Binding"
*
* Jackson 3 difference: JsonNode.asText() is now asString(). asInt() survives.
*/
public class G03TreeModelNavigation {
public record CustomerRecord(String name, String tier) { }
private static final String JSON = "{"
+ "\"orderId\":1001,"
+ "\"customer\":{\"name\":\"Alice\",\"tier\":\"gold\"},"
+ "\"items\":[{\"sku\":\"KB-01\",\"qty\":2},{\"sku\":\"MS-42\",\"qty\":1}]"
+ "}";
public static void main(String[] args) {
JsonMapper mapper = JsonMapper.builder().build();
JsonNode rootNode = mapper.readTree(JSON);
// path() never returns null — a missing node is a MissingNode.
String customerName = rootNode.path("customer").path("name").asString();
System.out.println("Customer: " + customerName);
for (JsonNode itemNode : rootNode.path("items")) {
System.out.println(itemNode.path("sku").asString() + " x" + itemNode.path("qty").asInt());
}
System.out.println("Has discount: " + rootNode.has("discountCode"));
// path() vs get() on an absent field — the difference that causes NPEs.
System.out.println("path(missing) : " + rootNode.path("nope")
+ " (class " + rootNode.path("nope").getClass().getSimpleName() + ")");
System.out.println("get(missing) : " + rootNode.get("nope"));
// Deep navigation stays null-safe all the way down.
System.out.println("deep path : '"
+ rootNode.path("a").path("b").path("c").asString("<default>") + "'");
// Switch from tree to data binding at any node.
CustomerRecord customer = mapper.treeToValue(rootNode.path("customer"), CustomerRecord.class);
System.out.println("treeToValue : " + customer);
}
}