1. Overview

In this tutorial, we're going to look at how we can ignore properties for serialization, but not for deserialization. So when Jackson is reading from JSON string, it will read the property and put into the target object. But when Jackson attempts to serialize the object, it will ignore the property.

For this purpose,  we'll use @JsonIgnore and @JsonIgnoreProperties.

2. Basic Usage for @JsonIgnoreProperties

The @JsonIgnoreProperties annotation lets us define ignored properties:

@Test
public void shouldSerialize_WithIgnoreOnClass() throws JsonProcessingException {

    @JsonIgnoreProperties("name")
    class Person {

        private int age = 12;
        private String name = "john";

        public int getAge() {
            return age;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    Person person = new Person();

    String json = objectMapper.writeValueAsString(person);

    assertThat(json).isEqualTo("{\"age\":12}");
}

Here, the name property is ignored and it is not in the JSON string. When we want to deserialize, the name property will also be ignored.

So we should follow a different way to make Jackson ignore a property during deserialization but not on serialization. Or vice versa.

3. allowGetters for Serialization-Only Object

Let's investigate @JsonIgnoreProperties.

The @JsonIgnoreProperties annotation has allowGetters and allowSetters attributes.

When we set allowGetters as true, Jackson treats the object as read-only. In other words, Jackson will ignore the property for deserialization but will use it for serialization.

To illustrate the usage, we have the following Person class. Note that we have @JsonIgnoreProperties on the class definition and we're setting allowGetters as true:

@JsonIgnoreProperties(value = "name", allowGetters = true)
private static class Person {

    private int age;
    private String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

When we want to deserialize, the name property is ignored:

@Test
public void shouldDeserialize_WithoutIgnored() throws IOException {
    final String json = "{\"age\":12,\"name\":\"john\"}";

    Person deserialized = objectMapper.readValue(json, Person.class);

    assertThat(deserialized.getName()).isNull();
    assertThat(deserialized.getAge()).isEqualTo(12);
}

So Jackson won't deserialize the name property here.

Next, we'll see what happens during serialization:

@Test
public void shouldSerialize_WithIgnored() throws IOException {
    Person person = new Person();
    person.setName("john");
    person.setAge(12);

    String json = objectMapper.writeValueAsString(person);

    assertThat(json).isEqualTo("{\"age\":12,\"name\":\"john\"}");
}

Here, Jackson doesn't ignore the name property and serializes it.

4. allowSetters for Deserialization-Only Object

Now let's continue with deserialization-only objects.

When we set allowSetters as true, Jackson treats the object as write-only. In other words, Jackson will ignore the property for serialization but will use it for deserialization.

We have a similar Person class. We've set allowSetters as true:

@JsonIgnoreProperties(value = "name", allowSetters = true)
private static class Person {

    private int age;
    private String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

When we want to deserialize, Jackson won't ignore the name property:

@Test
public void shouldDeserialize_WithIgnored() throws IOException {
    final String json = "{\"age\":12,\"name\":\"john\"}";

    Person deserialized = objectMapper.readValue(json, Person.class);

    assertThat(deserialized.getName()).isEqualTo("john");
    assertThat(deserialized.getAge()).isEqualTo(12);
}

However, when we want to serialize, Jackson ignores the name property:

@Test
public void shouldSerialize_WithoutIgnored() throws IOException {
    Person person = new Person();
    person.setName("john");
    person.setAge(12);

    String json = objectMapper.writeValueAsString(person);

    assertThat(json).isEqualTo("{\"age\":12}");
}

5. Summary

In this tutorial, we've detailed how to ignore properties only for serialization or deserialization.

Check out the source code for all examples over on Github.