Converting Java objects to JSON with Jackson
Categories:
Mastering JSON Serialization in Java with Jackson

Learn how to efficiently convert Java objects to JSON and vice-versa using the powerful Jackson library, covering core concepts and practical examples.
In modern application development, data interchange often relies on JSON (JavaScript Object Notation) due to its lightweight and human-readable format. When working with Java, the Jackson library stands out as the de facto standard for handling JSON serialization (Java object to JSON) and deserialization (JSON to Java object). This article will guide you through the essentials of using Jackson to seamlessly convert your Java objects into JSON strings and back again, enabling robust data communication in your applications.
Setting Up Jackson
Before we dive into code, you need to include the Jackson dependencies in your project. If you're using Maven, add the following to your pom.xml
file. For Gradle, the equivalent dependencies would be added to your build.gradle
.
<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-core</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.2</version>
</dependency>
Maven dependencies for Jackson Databind
Basic Object to JSON Serialization
The core class for performing serialization and deserialization in Jackson is ObjectMapper
. To convert a simple Java object into a JSON string, you instantiate ObjectMapper
and use its writeValueAsString()
method. Let's consider a simple User
class.
public class User {
private String name;
private int age;
private String email;
// Constructors
public User() {}
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// 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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", email='" + email + '\'' +
'}';
}
}
A simple Java POJO (Plain Old Java Object) for demonstration
import com.fasterxml.jackson.databind.ObjectMapper;
public class SerializationExample {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User("John Doe", 30, "john.doe@example.com");
try {
String jsonString = objectMapper.writeValueAsString(user);
System.out.println("Serialized JSON: " + jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Serializing a User object to JSON
The output of the above code will be a JSON string representing the User
object. Jackson automatically infers the property names from the getter methods (or fields if direct field access is enabled).
{"name":"John Doe","age":30,"email":"john.doe@example.com"}
Expected JSON output
flowchart TD A[Java Object (User)] --> B{ObjectMapper.writeValueAsString()} B --> C[JSON String] C --> D{Network/Storage} D --> E{ObjectMapper.readValue()} E --> F[Java Object (User)]
Basic Jackson Serialization and Deserialization Flow
Customizing Serialization with Annotations
Jackson provides a rich set of annotations to customize how your Java objects are serialized and deserialized. These annotations give you fine-grained control over property names, date formats, ignored fields, and more.
Here are some commonly used annotations:
@JsonProperty
: Renames a field in the JSON output.
@JsonIgnore
: Excludes a field from serialization/deserialization.
@JsonFormat
: Customizes date/time formats.
@JsonInclude
: Specifies when to include properties (e.g., NON_NULL
, NON_EMPTY
).
@JsonCreator
: Marks a constructor or factory method to be used for deserialization.import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
@JsonInclude(JsonInclude.Include.NON_NULL) // Only include non-null fields
public class Product {
@JsonProperty("product_id") // Rename 'id' to 'product_id' in JSON
private String id;
private String name;
private double price;
@JsonIgnore // Do not serialize this field
private String internalCode;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date manufacturedDate;
// Constructors, Getters, Setters
public Product() {}
public Product(String id, String name, double price, String internalCode, Date manufacturedDate) {
this.id = id;
this.name = name;
this.price = price;
this.internalCode = internalCode;
this.manufacturedDate = manufacturedDate;
}
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
public String getInternalCode() { return internalCode; }
public void setInternalCode(String internalCode) { this.internalCode = internalCode; }
public Date getManufacturedDate() { return manufacturedDate; }
public void setManufacturedDate(Date manufacturedDate) { this.manufacturedDate = manufacturedDate; }
}
Product class with Jackson annotations for custom serialization
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;
public class AnnotatedSerializationExample {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Product product = new Product("P101", "Laptop", 1200.50, "INT-ABC-123", new Date());
product.setInternalCode(null); // This field will be ignored due to @JsonInclude(NON_NULL)
try {
String jsonString = objectMapper.writeValueAsString(product);
System.out.println("Annotated JSON: " + jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Serializing the annotated Product object
{"product_id":"P101","name":"Laptop","price":1200.5,"manufacturedDate":"2023-10-27"}
Expected JSON output from annotated Product (date will vary)
Notice how internalCode
is absent (due to @JsonIgnore
and NON_NULL
for null value) and id
is renamed to product_id
. The manufacturedDate
is also formatted as yyyy-MM-dd
.
Deserialization: JSON to Java Object
Converting a JSON string back into a Java object is just as straightforward using ObjectMapper
's readValue()
method. You need to provide the JSON string and the target Java class.
import com.fasterxml.jackson.databind.ObjectMapper;
public class DeserializationExample {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"name\":\"Jane Doe\",\"age\":25,\"email\":\"jane.doe@example.com\"}";
try {
User user = objectMapper.readValue(jsonString, User.class);
System.out.println("Deserialized User: " + user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Deserializing a JSON string back to a User object
The readValue()
method intelligently maps the JSON fields to the corresponding properties in your Java class, using setters or direct field access. If your class uses annotations like @JsonProperty
, Jackson will respect those during deserialization as well.
@JsonCreator
on a parameterized constructor.