@JsonIgnoreProperties and @JsonIgnore annotations

JSON (JavaScript Object Notation) has become the de facto standard for data interchange in modern applications. In Java, the @JsonIgnoreProperties and @JsonIgnore annotations provide powerful tools for customizing the serialization and deserialization of JSON data.

This post explains how these annotations can control the serialization and deserialization of JSON data, allowing you to exclude specific fields.

Both @JsonIgnore and @JsonIgnoreProperties annotations serve similar purposes, however, the difference lies in their usage. The @JsonIgnore annotation is applied on the property or field level, while the @JsonIgnoreProperties annotation is applied on the class level.

So, what do these annotations do?

They help you ignore certain fields when serializing or deserializing an object. This means that if you don’t want specific fields to show up in your JSON or you don’t want to map some of the JSON keys back to your object, these annotations can help you achieve that.

@JsonIgnore

@JsonIgnore annotation is used at the field level, which means JsonIgnore annotation would be put on such a field that we don’t want to become a part of our JSON.

@JsonIgnore
private String firstName;

Now, we’ll explore how to serialize and deserialize an object using the @JsonIgnore annotation on a class field. Let’s consider a Person class with three fields – firstName, lastName, and age – along with their corresponding getters and setters.

We will use the @JsonIgnore annotation on the firstName field, as shown below.

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Person {

	@JsonIgnore // to ignore property during serialization or deserialization
	private String firstName;

	private String lastName;
	private int age;

	public Person() {
		super();
	}

	public Person(String firstName, String lastName, int age) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}

	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 int getAge() {
		return age;
	}

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

}
Serialization

ObjectMapper class is used to serialize the person object here.

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

public class Codekru {

	public static void main(String[] args) throws JsonProcessingException {
		Person person = new Person();
		person.setFirstName("Codekru");
		person.setLastName("Startup");
		person.setAge(1);
		ObjectMapper mapper = new ObjectMapper();
		System.out.println(mapper.writeValueAsString(person)); // serializaing person object
	}

}

Output –

{"lastName":"Startup","age":1}

You can see here that the firstName field is not serialized and is also not reflected in the JSON.

Let’s try to achieve the same while deserializing an object.

Deserialization

We will try to deserialize the below JSON back to our Person object.

{
  "lastName": "startup",
  "firstName": "codekru",
  "age": 1
}

Below is the program for the same

public class Codekru {

	public static void main(String[] args) throws IOException {
		ObjectMapper mapper = new ObjectMapper();
		String json = "{\r\n" + "  \"lastName\" : \"startup\",\r\n" + "  \"firstName\" : \"codekru\",\r\n"
				+ "  \"age\" : 1\r\n" + "}";
		Person person = mapper.readValue(json, Person.class);

		System.out.println("first Name: " + person.getFirstName());
		System.out.println("last Name: " + person.getLastName());
		System.out.println("Age: " + person.getAge());

	}

}

Output –

first Name: null
last Name: startup
Age: 1

You can see here that the firstName field is null, and all other fields have some values.

@JsonIgnoreProperties

@JsonIgnoreProperties annotation is used on the class level to exclude the fields from being serialized or deserialized.

@JsonIgnoreProperties({"fieldname1","fieldname2"})
public class Example{

We are going to use the same Person class and will use JsonIgnoreProperties annotation on the age field.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties({"age"})
public class Person {

	private String firstName;

	private String lastName;
	private int age;

	public Person() {
		super();
	}

	public Person(String firstName, String lastName, int age) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}

	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 int getAge() {
		return age;
	}

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


}
Serialization

Let’s try to serialize the object now.

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

public class Codekru {

	public static void main(String[] args) throws JsonProcessingException {
		Person person = new Person();
		person.setFirstName("Codekru");
		person.setLastName("Startup");
		person.setAge(1);
		ObjectMapper mapper = new ObjectMapper();
		System.out.println(mapper.writeValueAsString(person)); // serializaing person object
	}

}

Output –

{"firstName":"Codekru","lastName":"Startup"}

You can see here that the age field is not part of our resulting JSON.

Deserialization

It’s time to deserialize now. We will try to deserialize the below JSON.

{
  "lastName": "startup",
  "firstName": "codekru",
  "age": 1
}

Below is the program for deserializing the above JSON.

import com.fasterxml.jackson.databind.ObjectMapper;

public class Codekru {

	public static void main(String[] args) throws IOException {
		ObjectMapper mapper = new ObjectMapper();
		String json = "{\r\n" + "  \"lastName\" : \"startup\",\r\n" + "  \"firstName\" : \"codekru\",\r\n"
				+ "  \"age\" : 5\r\n" + "}";
		Person person = mapper.readValue(json, Person.class);

		System.out.println("first Name: " + person.getFirstName());
		System.out.println("last Name: " + person.getLastName());
		System.out.println("Age: " + person.getAge());

	}

}

Output –

first Name: codekru
last Name: startup
Age: 0

One thing to notice here is that the age value is printed as 0 in the output. But why is that?

During JSON deserialization, the age field was ignored because of the JsonIgnoreProperties annotation, resulting in no value being assigned to it. As a result, the age variable was assigned a default value corresponding to its data type, which in this case is an integer. Therefore, the default value for age is 0.

What if we try to deserialize a JSON containing a key that is not present as a field in our class? What will happen then?

Let’s have a look at the below JSON.

{
  "lastName": "startup",
  "firstName": "codekru",
  "age": 1,
  "hobbies": "Badminton"
}

Here we can see that one extra key, “hobbies”, is not present in our Person class ( have only three fields – firstName, lastName, and age). Let’s see what happens if we try to map it with our class.

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

public class Codekru {

	public static void main(String[] args) throws IOException {
		ObjectMapper mapper = new ObjectMapper();
		String json = "{\r\n"
				+ "  \"lastName\": \"startup\",\r\n"
				+ "  \"firstName\": \"codekru\",\r\n"
				+ "  \"age\": 1,\r\n"
				+ "  \"hobbies\": \"Badminton\"\r\n"
				+ "}";
		Person person = mapper.readValue(json, Person.class);

		System.out.println("first Name: " + person.getFirstName());
		System.out.println("last Name: " + person.getLastName());
		System.out.println("Age: " + person.getAge());

	}

}

Output –

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "hobbies" (class Test.Person), not marked as ignorable (2 known properties: , "lastName", "firstName"])
 at [Source: java.io.StringReader@6ab7a896; line: 5, column: 15] (through reference chain: Test.Person["hobbies"])
	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
	at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)

We received an error message indicating that the “hobbies” are not recognized. So, is there a solution to prevent this error from occurring?

Yes, there is a solution. The JsonIgnoreProperties feature has an attribute called “ignoreUnknown“. By setting this attribute to “true“, any unknown properties will be ignored during the object’s deserialization. However, note that this attribute won’t have any impact on serializing an object.

Syntax of using ignoreUnknown=true
@JsonIgnoreProperties(ignoreUnknown = true)
public class className {

}

Our Person class would now be.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true,value = {"age"})
public class Person {

	private String firstName;

	private String lastName;
	private int age;

	public Person() {
		super();
	}

	public Person(String firstName, String lastName, int age) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}

	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 int getAge() {
		return age;
	}

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


}

And now, let’s try to serialize the JSON again.

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

public class Codekru {

	public static void main(String[] args) throws IOException {
		ObjectMapper mapper = new ObjectMapper();
		String json = "{\r\n"
				+ "  \"lastName\": \"startup\",\r\n"
				+ "  \"firstName\": \"codekru\",\r\n"
				+ "  \"age\": 1,\r\n"
				+ "  \"hobbies\": \"Badminton\"\r\n"
				+ "}";
		Person person = mapper.readValue(json, Person.class);

		System.out.println("first Name: " + person.getFirstName());
		System.out.println("last Name: " + person.getLastName());
		System.out.println("Age: " + person.getAge());

	}

}

Output –

first Name: codekru
last Name: startup
Age: 0

We got no exceptions here, and the age field was also ignored. So, in this way, any unrecognized attribute can easily be ignored using the ignoreUnknown attribute

We hope that you have liked the article. If you have any doubts or concerns, please write us in the comments or mail us at [email protected].

References:
https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIgnoreProperties.html
https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIgnore.html

Other Jackson Annotations –

Liked the article? Share this on

Leave a Comment

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