@JsonIgnoreProperties and @JsonIgnore annotations

In this post, we are going to discuss two Jackson annotations –

@JsonIgnore and @JsonIgnoreProperties annotations are similar in their functionality but differ only because the @JsonIgnore annotation is used on the property or field level while the @JsonIgnoreProperties annotation is used on the class level.

So, what do these annotations do? These annotations help suppress (or ignore) one or more fields while serializing or deserializing an object. So, if you don’t want some of the fields to reflect in your JSON, or you don’t want to map some of the JSON keys back to your object, then these annotations will do the trick for you.

@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 will look at both serializing and deserializing the object while using the @JsonIgnore annotation on one of the class fields. Let’s take a Person class with three fields, firstName, lastName, and age, with 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 does the same thing as @JsonIgnore does. So, what is the difference between the two?

The difference is that @JsonIgnoreProperties annotation is used on the class level, whereas @JsonIgnore is on the field level. Below is how we use the JsonIgnoreProperites annotation if we want to ignore a particular field from our class.

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

We are going to use the same Person class and will use JsonIgnoreProperties annotation for 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?

Here, the age field was ignored while deserializing the JSON because of the @JsonIgnoreProperties annotation, and thus no value was assigned to it. So, a default value of the corresponding type is assigned to the age variable. In our case, the data type is an integer, so 0 will be the default value.

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: [email protected]; 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)

Ohh!!! We got an error saying it doesn’t recognize the “hobbies”. So, Is there any way of avoiding this error?

There is. JsonIgnoreProperties has one attribute named ignoreUnknown. If we set this attribute value to true, all unknown properties will be ignored during the deserialization of an object. ignoreUnknown attribute has no effect while 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

Here, we have no exceptions, 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 feel free to 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.