1. Overview

In this tutorial, we'll look at how to deserialize with private fields using Jackson. You can also check out Jackson serialization with private fields.

2. Can Jackson deserialize using private fields?

Let's start with Jackson's default behavior during deserialization.

Jackson can't deserialize into private fields with its default settings. Because it needs getter or setter methods.

public class Person {

    private int age;
}

Here, Person has one private field, age. But it doesn't have any getter/setter methods.

When we try to deserialize JSON string to Person class, we get an exception:

@Test(expected = JsonProcessingException.class)
public void shouldNotDeserialize_WithPrivateFields() throws IOException {
    final String json = "{\"age\":12}";

    objectMapper.readValue(json, Person.class);
}

Although we have a field named age in the Person class, Jackson can't map it and throws an exception.

3. Can we configure Jackson to use private fields during deserialization?

Now, we'll see different configuration options for using private fields during deserialization. Mainly, we'll change the visibility settings of Jackson for serialization/deserialization.

3.1. Change visibility with @JsonAutoDetect on the Class

Firstly, we'll use @JsonAutoDetect to change visibility settings on the class level:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class PersonWithAnnotation {

    private int age;
}

When we try to deserialize, it successfully deserializes:

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

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

    assertThat(deserialized.age).isEqualTo(12);
}

 

3.2. Change visibility with PropertyAccessor.FIELD on the ObjectMapper

Next, we'll configure visibility on the ObjectMapper level.

We have the Person class:

public class Person {

    private int age;
}

We'll change the visibility setting using PropertyAccessor.FIELD. This change affects all deserialization operations:

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

    objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    Person deserialized = objectMapper.readValue(json, Person.class);

    assertThat(deserialized.age).isEqualTo(12);
}

4. Summary

In this tutorial, we've investigated different options for changing property access settings using Jackson.

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