Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Jackson JSON Processing: A Comprehensive Guide

Tech May 10 4

Converting JSON to a Plain Old Java Object (POJO)

The ObjectMapper class is the primary entry point for Jackson. It can be used to convert JSON strings into Java objects and vice versa. Below is an example of deserializing a JSON string into a Person object and then serializing that object back to a formatted JSON string.

public class JsonPojoExample {
    public static void main(String[] args) {
        // ObjectMapper is thread-safe and should be reused
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonInput = "{"firstName":"Alice", "age":28}";

        try {
            // Deserialize JSON string to a Person object
            Person person = objectMapper.readValue(jsonInput, Person.class);
            System.out.println("Deserialized Person: " + person);

            // Enable pretty-printing for the output
            objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
            // Serialize the Person object back to a JSON string
            String jsonOutput = objectMapper.writeValueAsString(person);
            System.out.println("Serialized JSON:
" + jsonOutput);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String firstName;
    private int age;

    // Getters and setters are required for serialization/deserialization
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    @Override
    public String toString() {
        return "Person{firstName='" + firstName + "', age=" + age + "}";
    }
}

Serialization and Deserialization to Files

Jackson can also work directly with files. The following example demonstrates writing a Person object to a JSON file and then reading it back.

public class JsonFileHandler {
    public static void main(String[] args) {
        JsonFileHandler handler = new JsonFileHandler();
        try {
            Person person = new Person();
            person.setFirstName("Bob");
            person.setAge(35);

            // Serialize the object to a JSON file
            handler.serializeToFile(person, "./data/person.json");

            // Deserialize the object from the JSON file
            Person personFromFile = handler.deserializeFromFile("./data/person.json");
            System.out.println("Person from file: " + personFromFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Serializes a Java object to a JSON file.
     * @param object The object to serialize.
     * @param filePath The path to the output file.
     * @throws Exception if an error occurs during serialization.
     */
    public void serializeToFile(Object object, String filePath) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writeValue(new File(filePath), object);
    }

    /**
     * Deserializes a JSON file into a Java object.
     * @param filePath The path to the input file.
     * @param clazz The class of the object to deserialize into.
     * @return The deserialized object.
     * @throws Exception if an error occurs during deserialization.
     */
    public <t> T deserializeFromFile(String filePath, Class<t> clazz) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(new File(filePath), clazz);
    }
}
</t></t>

Binding to a Map

Jackson can bind complex JSON structures directly to a Map. This is useful when you don't have a predefined POJO or when the structure is highly dynamic.

public class JsonMapBinding {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();

        // Create a complex data structure to serialize
        Map<string object=""> dataMap = new HashMap<>();
        Person person = new Person();
        person.setFirstName("Charlie");
        person.setAge(42);
        dataMap.put("user", person);
        dataMap.put("title", "System Administrator");
        dataMap.put("isActive", true);
        int[] scores = {98, 95, 92};
        dataMap.put("performanceScores", scores);

        // Serialize the map to a JSON file
        // objectMapper.writeValue(new File("./data/user_data.json"), dataMap);

        // Deserialize the JSON file back into a map
        Map<string object=""> loadedMap = objectMapper.readValue(new File("./data/user_data.json"), Map.class);

        // Access the data from the map
        System.out.println("User: " + loadedMap.get("user"));
        System.out.println("Title: " + loadedMap.get("title"));
        System.out.println("Is Active: " + loadedMap.get("isActive"));

        // Access the array from the map
        List<integer> scoreList = (List<integer>) loadedMap.get("performanceScores");
        System.out.println("Scores: " + scoreList);
    }
}
</integer></integer></string></string>

Handling Generic Types

Deserializing generic types like List<User> or custom classes like PageResult<T> requires special handling to inform Jackson about the generic type information.

public class JsonGenericBinding {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User(1, "david@example.com");
        List<user> userList = new ArrayList<>();
        userList.add(user);

        PageResult<user> pageResult = new PageResult<>();
        pageResult.setItems(userList);

        String json = objectMapper.writeValueAsString(pageResult);

        // Method 1: Using TypeReference
        PageResult<user> pageResult1 = objectMapper.readValue(json, new TypeReference<pageresult>>() {});

        // Method 2: Using JavaType
        JavaType javaType = objectMapper.getTypeFactory().constructParametrizedType(PageResult.class, PageResult.class, User.class);
        PageResult<user> pageResult2 = objectMapper.readValue(json, javaType);

        // Handling a List of Users
        String listJson = objectMapper.writeValueAsString(userList);
        JavaType listType = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);
        List<user> deserializedUsers = objectMapper.readValue(listJson, listType);

        // Handling a Map of String to User
        Map<string user=""> userMap = new HashMap<>();
        userMap.put("admin", user);
        String mapJson = objectMapper.writeValueAsString(userMap);
        JavaType mapType = objectMapper.getTypeFactory().constructParametricType(HashMap.class, String.class, User.class);
        Map<string user=""> deserializedMap = objectMapper.readValue(mapJson, mapType);
    }
}

class User {
    private int id;
    private String email;
    // Constructor, getters, setters...
    public User(int id, String email) { this.id = id; this.email = email; }
    // ... other methods
}

class PageResult<t> {
    private List<t> items;
    // Constructor, getters, setters...
    public void setItems(List<t> items) { this.items = items; }
    // ... other methods
}
</t></t></t></string></string></user></user></pageresult></user></user></user>

Using the Jackson Tree Model

The Tree Model alllows you to parse JSON into a tree of JsonNode objects, which you can then navigate manually. This is useful for dynamic or complex JSON structures.

public class JsonTreeModel {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = "{"firstName":"Eve", "lastName":"Adams", "age":30, "isEmployed":true, "skills":["Java", "Spring", "SQL"]}";

        // Parse JSON string into a JsonNode tree
        JsonNode rootNode = objectMapper.readTree(jsonString);

        // Navigate the tree using path()
        JsonNode nameNode = rootNode.path("firstName");
        System.out.println("First Name: " + nameNode.asText());

        JsonNode ageNode = rootNode.path("age");
        System.out.println("Age: " + ageNode.asInt());

        JsonNode skillsNode = rootNode.path("skills");
        System.out.println("Skills:");
        for (JsonNode skill : skillsNode) {
            System.out.println(" - " + skill.asText());
        }

        // Reading from a file and converting to a POJO
        JsonNode fileNode = objectMapper.readTree(new File("./data/user_info.json"));
        UserInfo userInfo = objectMapper.treeToValue(fileNode, UserInfo.class);
        System.out.println("User Info from file: " + userInfo.getFullName());
    }
}

class UserInfo {
    private String fullName;
    // Constructor, getters, setters...
    public String getFullName() { return fullName; }
    // ... other methods
}

Streaming API for Large JSON

For very large JSON documents, the streaming API (JsonParser and JsonGenerator) is more memory-efficient as it processes the data token by token without loading the entire document into memory.

public class JsonStreamingApi {
    public static void main(String[] args) throws Exception {
        //writeJsonStream();
        readJsonStream();
    }

    /**
     * Writes JSON using JsonGenerator.
     */
    public static void writeJsonStream() throws Exception {
        JsonFactory jsonFactory = new JsonFactory();
        JsonGenerator jsonGenerator = jsonFactory.createGenerator(new File("./data/employee.json"), JsonEncoding.UTF8);

        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("name", "Frank Miller");
        jsonGenerator.writeNumberField("id", 101);
        jsonGenerator.writeBooleanField("isManager", true);

        jsonGenerator.writeFieldName("projects");
        jsonGenerator.writeStartArray();
        jsonGenerator.writeString("Project Alpha");
        jsonGenerator.writeString("Project Beta");
        jsonGenerator.writeEndArray();

        jsonGenerator.writeEndObject();
        jsonGenerator.close();
    }

    /**
     * Reads JSON using JsonParser.
     */
    public static void readJsonStream() throws Exception {
        JsonFactory jsonFactory = new JsonFactory();
        JsonParser jsonParser = jsonFactory.createParser(new File("./data/employee.json"));

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldName = jsonParser.getCurrentName();
            if ("name".equals(fieldName)) {
                jsonParser.nextToken();
                System.out.println("Name: " + jsonParser.getText());
            }
            if ("id".equals(fieldName)) {
                jsonParser.nextToken();
                System.out.println("ID: " + jsonParser.getIntValue());
            }
            if ("isManager".equals(fieldName)) {
                jsonParser.nextToken();
                System.out.println("Is Manager: " + jsonParser.getBooleanValue());
            }
            if ("projects".equals(fieldName)) {
                jsonParser.nextToken(); // Move to the start of the array
                System.out.println("Projects:");
                while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
                    System.out.println(" - " + jsonParser.getText());
                }
            }
        }
        jsonParser.close();
    }
}

Tags: jackson

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.