Object Mapping with Jackson Library

Beginner

Introduction

In this lab, we will learn how to use Jackson ObjectMapper class to map objects to JSON and JSON to objects. We will use a simple Java class named DemoClass and learn various techniques to read and write JSON data.

Create and Compile DemoClass

Create a new project in the ~/project directory and create a new DemoClass Java class. Paste the following code in DemoClass.java code file.

import java.util.Date;

public class DemoClass {
    private String field1;
    private Double field2;
    private Date dateField;

    // Constructors
    DemoClass() {}

    DemoClass(String field1, Double field2, Date dateField) {
        this.field1 = field1;
        this.field2 = field2;
        this.dateField = dateField;
    }

    // getters and setters
    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public Double getField2() {
        return field2;
    }

    public void setField2(Double field2) {
        this.field2 = field2;
    }

    public Date getDateField() {
        return dateField;
    }

    public void setDateField(Date dateField) {
        this.dateField = dateField;
    }
}

Compile the DemoClass Java class using the following command:

javac DemoClass.java

Reading Objects from a JSON File

We can use the readValue() method of the ObjectMapper class to read data from a JSON file into an object. Our JSON file contains just a single object's property-value pairs.

Create a new file named demo.json and paste the following JSON content in it.

{
    "field1": "Sample-1",
    "field2": 20.21,
    "dateField": "2021-07-30T14:20:30.000Z"
}

Use the following code to read the JSON file and map it to a DemoClass object.

import java.io.File;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperDemo {
    public static void main(String[] args) {
        try {
            String filePath = "demo.json";
            File file = new File(filePath);

            ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            DemoClass obj = objMapper.readValue(file, DemoClass.class);

            System.out.println("Field1: " + obj.getField1());
            System.out.println("Field2: " + obj.getField2());
            System.out.println("DateField: " + obj.getDateField());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The output will be:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Reading Objects from a JSON String

We can read data from a JSON string into an object. We will use the readValue() method of the ObjectMapper class. We also need to pass the class type to this method.

Add the following code to read data from a JSON string.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);

System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());

The output will be:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Reading Objects from a JSON URL

Reading objects from a URL is also pretty straightforward. We need to pass the URL object and the class type to the readValue() method.

Add the following code to read and map objects from a JSON URL.

import java.net.URL;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperDemo {
    public static void main(String[] args) {
        try {
            URL jsonFileUrl = new URL("file:demo.json");
            ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            DemoClass obj = objMapper.readValue(jsonFileUrl, DemoClass.class);

            System.out.println("Field1: " + obj.getField1());
            System.out.println("Field2: " + obj.getField2());
            System.out.println("DateField: " + obj.getDateField());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The output will be the same as Step 2.

Reading from a JSON String Array to an Object Array

Suppose a string contains multiple objects data (as an array) in JSON format. We can read all this data into an array of the DemoClass type using the ObjectMapper class.

Add the following code to read objects from a JSON string array to an object array.

String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
        " {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";

ObjectMapper objMapper = new ObjectMapper();
DemoClass[] objectArr = objMapper.readValue(jsonString, DemoClass[].class);

for (DemoClass obj : objectArr) {
    System.out.println("Field1: " + obj.getField1());
    System.out.println("Field2: " + obj.getField2());
    System.out.println("DateField: " + obj.getDateField());
    System.out.println();
}

The output will be:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Field1: Sample-2
Field2: 22.55
DateField: Sat Jul 31 14:20:30 UTC 2021

Reading from a JSON String Array to an Object List

We can read the objects into a list if we don't want to read data into a fixed-sized object array.

Add the following code to read objects from a JSON string array to an object list.

String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
        " {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";

ObjectMapper objMapper = new ObjectMapper();
ArrayList<DemoClass> objectList = objMapper.readValue(jsonString, new TypeReference<ArrayList<DemoClass>>(){});

for (DemoClass obj : objectList) {
    System.out.println("Field1: " + obj.getField1());
    System.out.println("Field2: " + obj.getField2());
    System.out.println("DateField: " + obj.getDateField());
    System.out.println();
}

The output will be the same as Step 5.

Reading from a JSON String Array to an Object Map

We can also read data from a JSON string into a map. Each property of the class will become a key, and the property value will become the value.

Add the following code to read data from a JSON string array into a map.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
Map<String, Object> objectMap = objMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});

for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

The output will be:

field1: Sample-1
field2: 20.21
dateField: 2021-07-30T14:20:30.000Z

Reading JSON to a JsonNode Object

The JsonNode class provides us more flexible way to parse JSON. We can use the readTree() method of ObjectMapper class to read JSON into a JsonNode object.

Add the following code to read JSON to a JsonNode object.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
JsonNode node = objMapper.readTree(jsonString);

System.out.println("Field1: " + node.get("field1").asText());
System.out.println("Field2: " + node.get("field2").asDouble());
System.out.println("DateField: " + node.get("dateField").asText());

The output will be the same as Step 2.

Configuring ObjectMapper

We can configure the ObjectMapper so that it can work with unexpected inputs.

Add the following code to configure the ObjectMapper to ignore any new properties.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"field3\":\"Unknown\"}";

ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);

System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());

The output will be the same as Step 2.

Working With Dates

By default, the ObjectMapper will map a java.util.date to a long value. This long value is the number of milliseconds passed since January 1, 1970.

Add the following code to demonstrate how to define a date format using the SimpleDateFormat to serialize the java.util.date.

ObjectMapper objMapper = new ObjectMapper();

SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
objMapper.setDateFormat(dateFormat);

DemoClass obj = new DemoClass("Sample-1", 20.21, new Date());
String jsonString = objMapper.writeValueAsString(obj);

System.out.println(jsonString);

The output will be:

{"field1":"Sample-1","field2":20.21,"dateField":"30-07-2021"}

Summary

In this lab, we learned how to use Jackson ObjectMapper class to map objects to JSON and JSON to objects. We learned how to read a JSON file into an object, read data from a JSON string and map it into an object, and read objects from a JSON string array to an object list or array. We also learned how to read a JSON string into a JsonNode object and configure the ObjectMapper to ignore new properties or null values for primitive types. Finally, we learned how to work with dates and use a specific date format while serializing the java.util.date.

Other Tutorials you may like