1. Overview

In this tutorial, we'll look at changing property names during serialization and deserialization. As a result, a field name in Java object will be different from the one in the JSON object. Similarly, we will be able to deserialize a field with a different name than in the Java object.

2. General POJO Serialization and Deserialization

Let's start with a quick overview of serialization/deserialization using Jackson.

Java objects generally conform to the rules of JavaBeans. So they have a field and associated getter/setter methods. In this case, Jackson uses the field name during serialization/deserialization.

Let's look at our sample class:

private static class Person {

    private String name;

    public String getName() {
        return name;
    }

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

Here, we have Person class with one field, name. Also we have getName() and setName() methods.

During serialization, the name field in Java object is serialized as name. So the field names are same both in Java and JSON objects.

@Test
public void shouldSerialize() throws JsonProcessingException {
    Person person = new Person();
    person.setName("john");

    String json = objectMapper.writeValueAsString(person);

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

During deserialization, something similar happens. The name field in JSON is assigned to name field in Java object.

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

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

    assertThat(person.getName()).isEqualTo("john");
}

3. Using @JsonProperty to Change Property Name

Now let's look at how we can change property names for serialization/deserialization.

For this purpose, we'll use @JsonProperty annotation. @JsonProperty lets us define a different name for a field. As a result, Jackson will use this new name during serialization and deserialization.

Let's look at our sample model first:

private static class PersonOnField {

    @JsonProperty("firstName")
    private String name;

    public String getName() {
        return name;
    }

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

Here, we've annotated name field with @JsonProperty("firstName"). 

During serialization, Jackson will use firstName instead of name:

@Test
public void shouldChangeName_ForSerialization_WhenJsonPropertyIsOnField() throws JsonProcessingException {
    PersonOnField personOnField = new PersonOnField();
    personOnField.setName("john");

    String json = objectMapper.writeValueAsString(personOnField);

    assertThat(json).isEqualTo("{\"firstName\":\"john\"}");
}

Similarly, during deserialization, Jackson will expect the firstName field in the JSON object.

@Test
public void shouldReadChangedName_ForDeserialization_WhenJsonPropertyIsOnField() throws IOException {
    final String json = "{\"firstName\":\"john\"}";

    PersonOnField person = objectMapper.readValue(json, PersonOnField.class);

    assertThat(person.getName()).isEqualTo("john");
}

3.1. @JsonProperty on Getter Methods

In the previous example, we've put @JsonProperty on a field. Now let's see what happens when we put @JsonProperty on getter/setter methods.

Firstly we'll put @JsonProperty("firstName") on getName() method. This is important because Jackson generally uses getter methods during serialization/deserialization:

private static class PersonOnGetter {

    private String name;

    @JsonProperty("firstName")
    public String getName() {
        return name;
    }

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

When we try to serialize the object, it writes firstName to the resulting JSON. Although it may not be too obvious, Jackson also uses firstName for deserializing JSON object to Java object.

@Test
public void shouldChangeName_ForSerialization_WhenJsonPropertyIsOnGetter() throws JsonProcessingException {
    PersonOnGetter personOnGetter = new PersonOnGetter();
    personOnGetter.setName("john");

    String json = objectMapper.writeValueAsString(personOnGetter);

    assertThat(json).isEqualTo("{\"firstName\":\"john\"}");
}

@Test
public void shouldReadChangedName_ForDeserialization_WhenJsonPropertyIsOnGetter() throws IOException {
    final String json = "{\"firstName\":\"john\"}";

    PersonOnGetter person = objectMapper.readValue(json, PersonOnGetter.class);

    assertThat(person.getName()).isEqualTo("john");
}

 

3.2. @JsonProperty On Setter Methods

Similar to getter methods, we can also put @JsonProperty on setter methods.

Now we'll put @JsonProperty("firstName") on setName() method:

private static class PersonOnSetter {

    private String name;

    public String getName() {
        return name;
    }

    @JsonProperty("firstName")
    public void setName(String name) {
        this.name = name;
    }
}

Again similar to getter methods, Jackson will use firstName for both serialization and deserialization.

@Test
public void shouldChangeName_ForSerialization_WhenJsonPropertyIsOnSetter() throws JsonProcessingException {
    PersonOnSetter personOnSetter = new PersonOnSetter();
    personOnSetter.setName("john");

    String json = objectMapper.writeValueAsString(personOnSetter);

    assertThat(json).isEqualTo("{\"firstName\":\"john\"}");
}

@Test
public void shouldReadChangedName_ForDeserialization_WhenJsonPropertyIsOnSetter() throws IOException {
    final String json = "{\"firstName\":\"john\"}";

    PersonOnSetter person = objectMapper.readValue(json, PersonOnSetter.class);

    assertThat(person.getName()).isEqualTo("john");
}

 

4. Summary

In this tutorial, we've looked at changing property names with @JsonProperty annotation using Jackson.

Check out the source code for code samples over on Github.