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
To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.
Need of Default ConstructorBy default, Java provides a default constructor(if there's no parameterized constructor) which is used by Jackson to parse the response into POJO or bean classes.
Without any annotations, the Jackson ObjectMapper uses reflection to do the POJO mapping. Because of the reflection, it works on all fields regardless of the access modifier.
ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.
@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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With