1. Overview

In this tutorial, we'll look at serializing private fields using Jackson.

2. Serialize Private Fields

Let's start with the default behavior of Jackson regarding private fields.

Jackson can't serialize private fields - without accessor methods - with its default settings.

We have the PrivatePerson class:

public class PrivatePerson {

    private String name;

    private int age;

    public PrivatePerson() {
    }

    public PrivatePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

PrivatePerson has two private fields with no public accessors.

If we try to serialize an instance of PrivatePerson, Jackson will throw an exception. Because Jackson can't find properties for serialization:

@Test(expected = JsonProcessingException.class)
public void shouldNotSerialize_WithPrivateFields() throws JsonProcessingException {
    PrivatePerson privatePerson = new PrivatePerson("john", 21);

    objectMapper.writeValueAsString(privatePerson);
}

3. Ignore Jackson Exceptions When Property List is Empty

Now we'll configure Jackson to ignore empty property list so that it will not throw an exception.

Jackson includes a serialization feature named SerializationFeature.FAIL_ON_EMPTY_BEANS. If this feature is set to false, Jackson doesn't throw an exception. Instead, it returns an empty JSON string.

We'll use PrivatePerson class:

@Test
public void shouldSerialize_WithPrivateFields_WhenConfigured() throws JsonProcessingException {
    PrivatePerson privatePerson = new PrivatePerson("john", 21);

    objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    String json = objectMapper.writeValueAsString(privatePerson);

    assertThat(json).isEqualTo("{}");
}

Here, we're setting SerializationFeature.FAIL_ON_EMPTY_BEANS as false. Then we're getting empty JSON string.

4. Configure Jackson to Use Private Fields during Serialization

Next, let's configure Jackson to adjust its visibility options. By doing so, it will start picking up private fields. There are two ways we can follow.

4.1. Change visibility with @JsonAutoDetect on the Class

Firstly, we'll annotate the class with @JsonAutoDetect and set fieldVisibility attribute as Visibility.ANY:

@Test
public void shouldSerialize_PrivateFields() throws JsonProcessingException {

    @JsonAutoDetect(fieldVisibility = Visibility.ANY)
    class Person {

        private int age = 12;
    }

    Person person = new Person();

    String json = objectMapper.writeValueAsString(person);

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

 

4.2. Change visibility with PropertyAccessor.FIELD on the ObjectMapper

Secondly, we'll set the visibility with PropertyAccessor.FIELD directly on ObjectMapper:

@Test
public void shouldSerialize_PrivateFields_ViaWriter() throws JsonProcessingException {

    class Person {

        private int age = 12;
    }

    Person person = new Person();

    objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    String json = objectMapper.writeValueAsString(person);

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

 

5. Summary

In this tutorial, we've looked at serialization of private fields. Moreover, we've seen different Jackson configuration options related to private fields serialization.

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