'How to deserialize JSON with @JsonCreator and @JsonGetter

I have the JSON looks like the following:

{
  "name":"John",
  "n_age":500
}

and I have a class Person:

public class Person {
    private final String name;
    private final int age;

    @JsonCreator
    public Person(@JsonProperty("name") String name) {
        this.name = name;
        this.age = 100;
    }

    public String getName() {
        return name;
    }

    @JsonGetter("n_age")
    public int getAge() {
        return age;
    }
}

I need to deserialize and serialize it, but when I'm trying to deserialize this JSON I get unexpected result.

public static void main(String... args) {
    ObjectMapper mapper = new ObjectMapper();
    Person person = mapper.readValue(args[0], Person.class);
    System.out.println(person.getAge()); // I got 500, but I expect 100.
}

Why when I'm trying to deserialize it the @JsonGetter annotation is used for it?
How can I disable @JsonGetter annotation when I try to deserialize the JSON?



Solution 1:[1]

If @JsonGetter is used as is currently, it will map property n_age to field age. To citate the docs - It can be used as an alternative to more general JsonProperty annotation (which is the recommended choice in general case).

To fix this behaviour, you need to:

  1. Tell jackson to ignore property n_age, otherwise you will get exception for unrecognized property not marked as ignorable - @JsonIgnoreProperties("n_age").
  2. Tell jackson to allow getters for ignored properties(basically make it readonly) - @JsonIgnoreProperties(value = {"n_age"}, allowGetters = true)

In the end, Person should look like this:

@JsonIgnoreProperties(value = {"n_age"}, allowGetters = true)
public class Person {

    private final String name;
    private final int age;

    @JsonCreator
    public Person(@JsonProperty("name") String name) {
        this.name = name;
        this.age = 100;
    }

    public String getName() {
        return name;
    }

    @JsonGetter("n_age")
    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Solution 2:[2]

I found the solution for fixing my issue, maybe it's a bad way, but it works for me as well. I'm ignoring the n_age property during deserialization and allowing getters during serialization. Thanks a lot @Chaosfire for the help!

@JsonIgnoreProperties({"n_age"}, allowGetters = true)
public class Person {

    private final String name;
    private final int age;

    @JsonCreator
    public Person(@JsonProperty("name") String name) {
        this.name = name;
        this.age = 100;
    }

    public String getName() {
        return name;
    }

    @JsonGetter("n_age")
    public int getAge() {
        return age;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 John