I try to deserialize a JSON object that I receive in my API using the following code:
ObjectMapper mapper = new ObjectMapper();
ExampleDto ed = mapper.readValue(req.body(), ExampleDto.class);
My class uses Lombok to generate constructors, getters and setters, and looks like this:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExampleDto {
private String name = "";
private List<String> values = new LinkedList<>();
}
Both properties should be optional, and use the default value specified in the class definition if they are not provided. However, if I now try to deserialize the JSON
{name: "Foo"}
the values
field is null
. From my understanding, and all example code I found, values
should be an empty list.
Edit: Not a duplicate, as I'm using Lombok without Optionals
@AllArgsConstructor
creates the following constructor
@ConstructorProperties({"name", "values"})
ExampleDto(String name, List<String> values) {
this.name = name;
this.values = values;
}
The constructor is annotated with @ConstructorProperties
which means a property-based creator (argument-taking constructor or factory method) is available to instantiate values from JSON object so jackson-databind uses this constructor to instantiate an object from ExampleDto
class.
When the following line executes
mapper.readValue("{\"name\": \"Foo\"}", ExampleDto.class);
because there's no value for values
in the provided JSON, null
is passed for the second argument when the constructor is invoked.
If you remove @AllArgsConstructor
annotation jackson-databind would use setter methods to initialize the object and in this case values
would not be null