Part 6: tree navigation, path() vs get(), treeToValue
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user