I have the answer to my own question, so I post both the answer and solution, as explicitly encouraged by Jeff Atwood. My question was originally for Kotlin, but while trying to find a solution, I also tried Java, so I provide the question and solution in both Java and Kotlin.)
Question in Kotlin
Given this deserializable Product
class:
data class Product(val name: String, val prices: List<Int>)
and this json string that lacks the prices
field:
{"name": "Computer"}
how can I deserialize the json string to a Product
object using Jackson?
What I have tried in Kotlin
I tried this:
data class Product(val name: String, val prices: List<Int>)
// Missing "prices" field
val json = """{"name": "Computer"}"""
// "prices" field included works fine
// val json = """{"name": "Computer", "prices": [1,2,3]}"""
val mapper = ObjectMapper().registerKotlinModule()
val product = mapper.readValue<Product>(json)
println(product)
but it results in this exception:
com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of
[simple type, class MainKt$main$Product] value failed for JSON property prices due to
missing (therefore NULL) value for creator parameter prices which is a non-nullable type
at [Source: (String)"{"name": "Computer"}"; line: 1, column: 20]
(through reference chain: MainKt$main$Product["prices"])
When using Java
For Java the Product
class would be:
class Product {
private String name;
private List<Integer> prices;
public Product(String name, List<Integer> prices) {
this.name = name;
this.prices = prices;
}
@Override
public String toString() {
return "Product{name='" + name + "\", prices=" + prices + '}';
}
}
with this Jackson code:
String json = "{\"name\": \"Computer\"}";
// String json = "{\"name\": \"Computer\", \"prices\": [1,2,3]}";
ObjectMapper mapper = new ObjectMapper();
// ParameterNamesModule is needed for non-arg constructor when not using Jackson annotations
mapper.registerModule(new ParameterNamesModule());
Product product = mapper.readValue(json, Product.class);
// Shows "prices=null", while "prices=[]" is required
System.out.println(product);
But this sets prices
to null
instead of an empty list.