REST Assured Tutorial 42 – Ignore Unknown Properties During Deserialization Using ObjectMapper – Jackson API

Introduction

As a part of End to End REST Assured Tutorial, in this post, We will learn about how unknown properties during deserialization creates a problem and how can we avoid them using ObjectMapper class of Jackson API.

Prerequisite

Ignoring unknown properties using @JsonIgnoreProperties

We can ignore unknown properties during deserialization using an annotation called @JsonIgnoreProperties provided by Jackson. We have covered this topic already. Refer that below:-

Ignore Unknown Properties During Deserialization Using @JsonIgnoreProperties

Required Java Library

Since we are using Jackson API of Java for this example, make sure you have the latest dependency of Jackson Databind in your project classpath. I have used below Jackson dependency for this post:-



    com.fasterxml.jackson.core
    jackson-databind
    2.11.1

Understand the meaning of known and unknown properties

Before we go for an actual topic let’s understand the meaning of words “known” and “unknown” properties. If a property is included in a POJO class or if a property exists in POJO class then it is a known property for that POJO class. A property that is not known to a POJO class is unknown. Let’s see the behavior when a known property is missing during deserialization.

Missing known properties during deserialization

Suppose we have a POJO as below:-

package JacksonTutorials;

public class Employee {

	// private variables or data members of pojo class
	private String firstName;
	private String lastName;
	private String gender;
	private int age;
	private double salary;
	private boolean married;
	
	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public boolean getMarried() {
		return married;
	}
	public void setMarried(boolean married) {
		this.married = married;
	} 	
}

Deserialize with some missing known properties

We will not include all known properties in JSON during deserialization as shown below:-

package JacksonTutorials;

import org.testng.annotations.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DeserializationWithMissingKnownProperties {

	@Test
	public void deserializationWithMissingKnownProperties() throws JsonMappingException, JsonProcessingException
	{
		String employeeString = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\" : \"Mahajan\",\r\n" + 
				"  \"gender\" : \"Male\"\r\n" +
				"}";
		
		ObjectMapper objectMapper = new ObjectMapper();
		//objectMapper.con
		Employee employee = objectMapper.readValue(employeeString, Employee.class);
		System.out.println("Deserialization...");
		System.out.println("First name :- "+employee.getFirstName());
		System.out.println("Last name :- "+employee.getLastName());
		System.out.println("Age :- "+employee.getAge());
		System.out.println("Gender :- "+employee.getGender());
		System.out.println("Salary :- "+employee.getSalary());
		System.out.println("Married :- "+employee.getMarried());

	}
}
Output
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 0
Gender :- Male
Salary :- 0.0
Married :- false

In JSON string three known properties are missing i.e. age, salary, and married. After deserialization, these fields have a default value. There is no error thrown for those missing values for known properties.

Additional unknown properties during deserialization

In the previous example, we had missing known properties in our JSON. Now we will have some additional unknown properties in JSON and observe behavior during deserialization.

Deserialize with some additional unknown properties

package JacksonTutorials;

import org.testng.annotations.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DeserializationWithAdditionalUnknownProperties {

	@Test
	public void deserializationWithAdditionalUnknownProperties() throws JsonMappingException, JsonProcessingException
	{
		String employeeString = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\" : \"Mahajan\",\r\n" + 
				"  \"gender\" : \"Male\",\r\n" + 
				"  \"age\" : 29,\r\n" + 
				"  \"salary\" : 12323.56,\r\n" + 
				"  \"married\" : false,\r\n" + 
				"  \"fullName\" : \"Amod Mahajan Gupta\",\r\n" + 
				"  \"eligibleForVote\" : false\r\n" + 
				"}";
		
		ObjectMapper objectMapper = new ObjectMapper();
		//objectMapper.con
		Employee employee = objectMapper.readValue(employeeString, Employee.class);
		System.out.println("Deserialization...");
		System.out.println("First name :- "+employee.getFirstName());
		System.out.println("Last name :- "+employee.getLastName());
		System.out.println("Age :- "+employee.getAge());
		System.out.println("Gender :- "+employee.getGender());
		System.out.println("Salary :- "+employee.getSalary());
		System.out.println("Married :- "+employee.getMarried());

	}
}

There are some additional unknown fields that are present in JSON string i.e. fullName and eligibleForVote. When we try to deserialize above JSON string we get the output as below:-

Output
[RemoteTestNG] detected TestNG version 7.0.1
FAILED: deserializationWithMissingKnownProperties
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "fullName" (class JacksonTutorials.Employee), not marked as ignorable (6 known properties: "lastName", "married", "salary", "firstName", "age", "gender"])
 at [Source: (String)"{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false,
  "fullName" : "Amod Mahajan Gupta",
  "eligibleForVote" : false
}"; line: 8, column: 17] (through reference chain: JacksonTutorials.Employee["fullName"])

As you can see deserialization failed at the encounter of first unknown property “fullName”. It also gives a list of all known properties.

ObjectMapper configuration to ignore unknown properties

In this post, we ignored unknown properties during deserialization using @JsonIgnoreProperties which works at the class level. If you do not have access to POJO class or you are not allowed to edit POJO classes then you can go for ObjectMapper level configuration.

We need to use enum DeserializationFeature to set the value of “FAIL_ON_UNKNOWN_PROPERTIES” as false. There is no need to make any change in the POJO class.

ObjectMapper Configuration Code

package JacksonTutorials;

import org.testng.annotations.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DeserializationWithAdditionalUnknownPropertiesObjectMapper {

	@Test
	public void deserializationWithAdditionalUnknownProperties() throws JsonMappingException, JsonProcessingException
	{
		String employeeString = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\" : \"Mahajan\",\r\n" + 
				"  \"gender\" : \"Male\",\r\n" + 
				"  \"age\" : 29,\r\n" + 
				"  \"salary\" : 12323.56,\r\n" + 
				"  \"married\" : false,\r\n" + 
				"  \"fullName\" : \"Amod Mahajan Gupta\",\r\n" + 
				"  \"eligibleForVote\" : false\r\n" + 
				"}";
		
		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		//objectMapper.con
		Employee employee = objectMapper.readValue(employeeString, Employee.class);
		System.out.println("Deserialization...");
		System.out.println("First name :- "+employee.getFirstName());
		System.out.println("Last name :- "+employee.getLastName());
		System.out.println("Age :- "+employee.getAge());
		System.out.println("Gender :- "+employee.getGender());
		System.out.println("Salary :- "+employee.getSalary());
		System.out.println("Married :- "+employee.getMarried());

	}
}
Output
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false

You can see how deserialization happened successfully with unknown properties present in the JSON string.

You can download/clone the above sample project from here.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning

Find all Selenium related posts here, all API manual and automation related posts here, and find frequently asked Java Programs here.

Many other topics you can navigate through the menu.

1 thought on “REST Assured Tutorial 42 – Ignore Unknown Properties During Deserialization Using ObjectMapper – Jackson API

  1. Hi Amod, Thanks for sharing the article.
    If you are trying deserailze the unknown property during the getter method will not allow as we dont have getter and setter for Fullname field. I mean if you are trying below line of code
    emp.getFullname() //Since this is not in POJO class. How to simuate the error which you have encountered.

Leave a Reply

Your email address will not be published. Required fields are marked *