DEV Community

Sadiul Hakim
Sadiul Hakim

Posted on

Jackson Tutorial: Comprehensive Guide with Examples

1. What is Jackson?

Jackson is a high-performance JSON processor for Java. It's the de facto standard library for:

  • Serializing Java objects to JSON
  • Deserializing JSON to Java objects
  • Manipulating JSON data (reading, writing, traversing)
  • Data binding between JSON and Java objects

Jackson is widely used in Spring Framework, RESTful web services, and any application that needs to process JSON data.

2. How to Add Jackson to Your Project

Maven (pom.xml)

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.15.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</groupId>
        <version>2.15.2</version>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

Gradle (build.gradle)

dependencies {
    implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
}
Enter fullscreen mode Exit fullscreen mode

3. ObjectMapper and Its Creation

The ObjectMapper is the main class in Jackson that provides functionality for reading and writing JSON.

Creating ObjectMapper from Empty Constructor

import com.fasterxml.jackson.databind.ObjectMapper;

// Simplest way to create ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Enter fullscreen mode Exit fullscreen mode

Creating ObjectMapper from File

import java.io.File;
import com.fasterxml.jackson.databind.ObjectMapper;

// Create ObjectMapper and read JSON from file
ObjectMapper mapper = new ObjectMapper();
File jsonFile = new File("data.json");
MyObject obj = mapper.readValue(jsonFile, MyObject.class);
Enter fullscreen mode Exit fullscreen mode

Creating ObjectMapper from InputStream

import java.io.InputStream;
import com.fasterxml.jackson.databind.ObjectMapper;

// Create ObjectMapper and read JSON from InputStream
ObjectMapper mapper = new ObjectMapper();
try (InputStream inputStream = getClass().getResourceAsStream("/data.json")) {
    MyObject obj = mapper.readValue(inputStream, MyObject.class);
}
Enter fullscreen mode Exit fullscreen mode

4. Important ObjectMapper Methods

readValue() - Convert JSON to Java Object

// From String
String jsonString = "{\"name\":\"John\", \"age\":30}";
Person person = mapper.readValue(jsonString, Person.class);

// From File
Person person = mapper.readValue(new File("person.json"), Person.class);

// From URL
Person person = mapper.readValue(new URL("http://example.com/person.json"), Person.class);
Enter fullscreen mode Exit fullscreen mode

writeValueAsString() - Convert Java Object to JSON String

Person person = new Person("John", 30);
String jsonString = mapper.writeValueAsString(person);
System.out.println(jsonString); // Output: {"name":"John","age":30}
Enter fullscreen mode Exit fullscreen mode

convertValue() - Convert Between Types

// Convert from one type to another (useful for Map to Object conversion)
Map<String, Object> map = new HashMap<>();
map.put("name", "John");
map.put("age", 30);

Person person = mapper.convertValue(map, Person.class);
Enter fullscreen mode Exit fullscreen mode

readTree() - Parse JSON into Tree Model

String jsonString = "{\"name\":\"John\", \"age\":30, \"hobbies\":[\"reading\", \"swimming\"]}";
JsonNode rootNode = mapper.readTree(jsonString);

// Access values
String name = rootNode.get("name").asText(); // "John"
int age = rootNode.get("age").asInt(); // 30
JsonNode hobbies = rootNode.get("hobbies"); // Array node
Enter fullscreen mode Exit fullscreen mode

Other Important Methods

// Write JSON to file
mapper.writeValue(new File("output.json"), person);

// Pretty print JSON
String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);

// Configure ObjectMapper
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Enter fullscreen mode Exit fullscreen mode

5. JsonSerializer and JsonDeserializer

Custom JsonSerializer Example

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * Custom serializer for LocalDate objects to format them as "yyyy-MM-dd"
 */
public class LocalDateSerializer extends JsonSerializer<LocalDate> {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider) 
            throws IOException {
        gen.writeString(value.format(formatter));
    }
}
Enter fullscreen mode Exit fullscreen mode

Custom JsonDeserializer Example

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * Custom deserializer to convert string "yyyy-MM-dd" to LocalDate
 */
public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) 
            throws IOException {
        String dateStr = p.getText();
        return LocalDate.parse(dateStr, formatter);
    }
}
Enter fullscreen mode Exit fullscreen mode

Using Custom Serializer/Deserializer in a Class

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.LocalDate;

public class Person {
    private String name;
    private int age;

    @JsonSerialize(using = LocalDateSerializer.class)
    @JsonDeserialize(using = LocalDateDeserializer.class)
    private LocalDate birthDate;

    // Constructors, getters, and setters
    public Person() {}

    public Person(String name, int age, LocalDate birthDate) {
        this.name = name;
        this.age = age;
        this.birthDate = birthDate;
    }

    // Getters and setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    public LocalDate getBirthDate() { return birthDate; }
    public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; }
}
Enter fullscreen mode Exit fullscreen mode

6. Converting Java Object to JSON and Vice Versa

Java Object to JSON

ObjectMapper mapper = new ObjectMapper();

// Create a Person object
Person person = new Person("Alice", 25, LocalDate.of(1998, 5, 15));

// Convert to JSON string
String jsonString = mapper.writeValueAsString(person);
System.out.println(jsonString);
// Output: {"name":"Alice","age":25,"birthDate":"1998-05-15"}

// Convert to JSON file
mapper.writeValue(new File("person.json"), person);
Enter fullscreen mode Exit fullscreen mode

JSON to Java Object

ObjectMapper mapper = new ObjectMapper();

// From JSON string
String jsonString = "{\"name\":\"Bob\",\"age\":30,\"birthDate\":\"1993-02-10\"}";
Person person = mapper.readValue(jsonString, Person.class);

// From JSON file
Person personFromFile = mapper.readValue(new File("person.json"), Person.class);

// From URL
Person personFromUrl = mapper.readValue(
    new URL("http://example.com/api/person/123"), Person.class);
Enter fullscreen mode Exit fullscreen mode

7. Manual JSON Construction with JsonNode

Using mapper.createObjectNode() and mapper.createArrayNode()

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;

ObjectMapper mapper = new ObjectMapper();

// Create an empty object node
ObjectNode personNode = mapper.createObjectNode();

// Add properties to the object
personNode.put("name", "John");
personNode.put("age", 30);
personNode.put("isStudent", false);

// Create an array node
ArrayNode hobbiesNode = mapper.createArrayNode();
hobbiesNode.add("Reading");
hobbiesNode.add("Swimming");
hobbiesNode.add("Coding");

// Add array to object
personNode.set("hobbies", hobbiesNode);

// Create a nested object
ObjectNode addressNode = mapper.createObjectNode();
addressNode.put("street", "123 Main St");
addressNode.put("city", "New York");
addressNode.put("zipCode", "10001");

personNode.set("address", addressNode);

// Convert to JSON string
String jsonString = mapper.writeValueAsString(personNode);
System.out.println(jsonString);
/* Output:
{
  "name": "John",
  "age": 30,
  "isStudent": false,
  "hobbies": ["Reading", "Swimming", "Coding"],
  "address": {
    "street": "123 Main St",
    "city": "New York",
    "zipCode": "10001"
  }
}
*/

// Convert JsonNode back to Java object
Person person = mapper.treeToValue(personNode, Person.class);
Enter fullscreen mode Exit fullscreen mode

Additional Important Topics

Handling Date and Time

ObjectMapper mapper = new ObjectMapper();

// Configure date format
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

// For Java 8 Date/Time API, register the JSR310 module
// Add dependency: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Enter fullscreen mode Exit fullscreen mode

Handling Polymorphic Types

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
    private String name;
    // getters and setters
}

public class Dog extends Animal {
    private String breed;
    // getters and setters
}

public class Cat extends Animal {
    private boolean likesCream;
    // getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Ignoring Properties

// Ignore properties during serialization
@JsonIgnoreProperties({"internalId", "secretKey"})
public class User {
    private String name;
    private String email;

    @JsonIgnore // Ignore individual property
    private String password;

    // getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Handling Null Values

// Configure how to handle null values
mapper.setSerializationInclusion(Include.NON_NULL); // Ignore null fields
mapper.setSerializationInclusion(Include.NON_EMPTY); // Ignore empty collections and strings

// Or use annotation on specific fields
public class Product {
    @JsonInclude(Include.NON_NULL)
    private String description;

    // getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Summary

Jackson is a powerful and flexible library for JSON processing in Java. Key takeaways:

  1. ObjectMapper is the central class for reading/writing JSON
  2. Use readValue() to convert JSON to Java objects
  3. Use writeValueAsString() to convert Java objects to JSON
  4. Create custom JsonSerializer and JsonDeserializer for complex types
  5. Use JsonNode for tree model and manual JSON construction
  6. Configure ObjectMapper with various features for different needs

Top comments (0)