1. Overview
In this tutorial, we'll investigate how we can serialize properties with different access modifiers. Additionally, we'll look at the usage of accessor methods during serialization.
2. Serializing Package-private fields
Let's start with package-private fields.
By default, Jackson can't serialize package-private fields. This is because Jackson needs public accessor methods for getting field values:
public class DefaultPerson {
String name;
int age;
public DefaultPerson() {
}
public DefaultPerson(String name, int age) {
this.name = name;
this.age = age;
}
}
Here, DefaultPerson class has two package-private fields with no public accessors.
Similar to private field serialization, serialization of package-private fields results in an exception:
@Test(expected = JsonProcessingException.class)
public void shouldNotSerialize_WithDefaultFields() throws JsonProcessingException {
DefaultPerson defaultPerson = new DefaultPerson("john", 21);
objectMapper.writeValueAsString(defaultPerson);
}
This is the case when we use Jackson with its default settings. However, we can change the visibility settings of Jackson to serialize package-private fields.
3. Serialize Public Fields using Jackson
Now, let's look at public field serialization.
Unlike package-private fields, Jackson can serialize public fields even if they don't have public accessors.
We have the PublicPerson class:
public class PublicPerson {
public String name;
public int age;
public PublicPerson() {
}
public PublicPerson(String name, int age) {
this.name = name;
this.age = age;
}
}
When we serialize an instance of PublicPerson, it successfully runs:
@Test
public void shouldSerialize_WithPublicFields() throws JsonProcessingException {
PublicPerson publicPerson = new PublicPerson("john", 21);
String json = objectMapper.writeValueAsString(publicPerson);
assertThat(json).isEqualTo("{\"name\":\"john\",\"age\":21}");
}
4. Serialize with Getter Methods
Jackson can also serialize with getter methods even if the fields are private:
public class GetterPerson {
private String name;
private int age;
public GetterPerson() {
}
public GetterPerson(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Here we have GetterPerson with two fields and corresponding getter methods.
When Jackson serializes an instance, it extracts the JSON field names from the JavaBean style methods:
@Test
public void shouldSerialize_WithGetters() throws JsonProcessingException {
GetterPerson getterPerson = new GetterPerson("john", 21);
String json = objectMapper.writeValueAsString(getterPerson);
assertThat(json).isEqualTo("{\"name\":\"john\",\"age\":21}");
}
Here, name is extracted from getName() and age is extracted from getAge() method.
5. Serialize Custom JavaBean Style Methods
In a class, there can be methods that don't have a field directly backing it. However, if this method conforms to JavaBean rules, Jackson uses it in serialization:
public class CustomGetterPerson {
private String name;
private int age;
public CustomGetterPerson() {
}
public CustomGetterPerson(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return 999;
}
public String getName() {
return name;
}
public int getPreviousAge() {
return age - 1;
}
public int nextAge() {
return age + 1;
}
}
Here, the getPreviousAge() method doesn't have a backing field, previousAge.
When Jackson serializes the instance, resulting JSON also includes a field named as previousAge. Note that serialized class doesn't have a field with that name, but has a method. Also note that, since nextAge() method isn't a valid JavaBean method, it isn't included in resulting JSON:
@Test
public void shouldSerialize_WithCustomGetter_AndAdditionalMethods() throws JsonProcessingException {
CustomGetterPerson customGetterPerson = new CustomGetterPerson("john", 21);
String json = objectMapper.writeValueAsString(customGetterPerson);
assertThat(json).isEqualTo("{\"name\":\"john\",\"age\":999,\"previousAge\":20}");
}
6. Summary
In this tutorial, we've investigated serializing properties with different access modifiers. Additionally, we've investigated the usage of methods during serialization.
As always, the source code is available on Github.