import com.fasterxml.jackson.databind.*; ObjectMapper mapper = new ObjectMapper(); String json = """ { "id": 42, "name": "Alice", "active": true, "score": 98.5, "tags": ["admin", "editor"], "address": { "city": "London", "zip": "EC1A" } } """; JsonNode root = mapper.readTree(json); // Read scalar fields int id = root.get("id").asInt(); // 42 String name = root.get("name").asText(); // "Alice" boolean active = root.get("active").asBoolean(); // true double score = root.get("score").asDouble(); // 98.5 // Safe navigation — path() returns MissingNode instead of null String city = root.path("address").path("city").asText(); // "London" String missing = root.path("nonexistent").asText("default"); // "default" // Array access JsonNode tags = root.get("tags"); for (JsonNode tag : tags) { System.out.println(tag.asText()); // admin, editor } // Check node type System.out.println(root.get("id").isInt()); // true System.out.println(root.get("name").isTextual()); // true System.out.println(root.get("tags").isArray()); // true System.out.println(root.get("address").isObject()); // true Use path() rather than get() for safe navigation — get() returns null for missing fields, while path() returns a MissingNode that safely returns empty/default values from accessor methods.
ClassJSON typeKey methods
ObjectNode{"key": value}get(field), put(), set(), remove(), fields()
ArrayNode[elem, ...]get(index), add(), insert(), remove(), size()
TextNode"string"asText(), textValue()
IntNode42asInt(), intValue()
LongNode1234567890123asLong(), longValue()
DoubleNode3.14asDouble(), doubleValue()
BooleanNodetrue/falseasBoolean(), booleanValue()
NullNodenullisNull()
MissingNode(absent field)isMissingNode()
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.node.*; ObjectMapper mapper = new ObjectMapper(); ObjectNode root = mapper.createObjectNode(); // Scalar fields root.put("id", 42); root.put("name", "Alice"); root.put("active", true); root.put("score", 98.5); root.putNull("deletedAt"); // Nested object ObjectNode address = mapper.createObjectNode(); address.put("city", "London"); address.put("zip", "EC1A"); root.set("address", address); // Array ArrayNode tags = mapper.createArrayNode(); tags.add("admin"); tags.add("editor"); root.set("tags", tags); // Fluent chaining ObjectNode built = mapper.createObjectNode() .put("x", 1) .put("y", 2); // Serialise the tree String json = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(root); System.out.println(json); JsonNode root = mapper.readTree(existingJson); ObjectNode obj = (ObjectNode) root; // Add / update fields obj.put("version", 2); obj.set("metadata", mapper.createObjectNode().put("source", "api")); // Remove a field obj.remove("internalId"); // Rename a field JsonNode val = obj.remove("old_name"); if (val != null) obj.set("new_name", val); // Modify an array — append an element ArrayNode tags = (ArrayNode) obj.get("tags"); tags.add("superuser"); // Remove element at index 0 tags.remove(0); // Deep merge — Jackson 2.9+ ObjectNode patch = mapper.createObjectNode().put("score", 100); obj.setAll(patch); // overlay patch fields onto obj // Convert back to string String updated = mapper.writeValueAsString(obj); Cast to ObjectNode or ArrayNode only after checking isObject() or isArray() — otherwise you risk a ClassCastException if the JSON structure does not match your assumption. import com.fasterxml.jackson.databind.*; record User(int id, String name, boolean active) {} ObjectMapper mapper = new ObjectMapper(); // POJO → Tree User user = new User(1, "Alice", true); JsonNode tree = mapper.valueToTree(user); System.out.println(tree.get("name").asText()); // Alice // Tree → POJO String json = "{\"id\":2,\"name\":\"Bob\",\"active\":false}"; JsonNode node = mapper.readTree(json); User restored = mapper.treeToValue(node, User.class); System.out.println(restored.name()); // Bob // Extract a sub-tree as a POJO String nested = "{\"user\":{\"id\":3,\"name\":\"Carol\",\"active\":true}}"; JsonNode root = mapper.readTree(nested); User carol = mapper.treeToValue(root.get("user"), User.class); JsonNode root = mapper.readTree(json); // Iterate object fields if (root.isObject()) { root.fields().forEachRemaining(entry -> { String key = entry.getKey(); JsonNode val = entry.getValue(); System.out.println(key + " => " + val.getNodeType()); }); } // Iterate field names only root.fieldNames().forEachRemaining(System.out::println); // Iterate array elements JsonNode tags = root.get("tags"); if (tags != null && tags.isArray()) { for (int i = 0; i < tags.size(); i++) { System.out.println(i + ": " + tags.get(i).asText()); } } // Stream elements (Jackson 2.13+) // StreamSupport.stream(tags.spliterator(), false) // .map(JsonNode::asText) // .forEach(System.out::println); // Find all nodes with a given field name (recursive) List<JsonNode> allIds = root.findValues("id"); allIds.forEach(n -> System.out.println(n.asInt()));