I am using jackson-datatype-jdk8 library to deserialize from json to Optional fields in my POJO, configured via:
objectMapper.registerModule(new Jdk8Module());
I am using Optional because I need to able to distinguish between the field being present in the json but with a value of null, which deserializes as Optional.empty(), and not having the field at all, which deserializes as null (in order to implement PATCH rest method).
This works perfectly for simple types, but not for Optional of Lists, eg:
class MyPojo {
String plainString; // Works
Optional<String> optionalString; // Works
List<String> plainStrings; // Works
Optional<List<String>> optionalStrings; // Explodes if json contains data, eg "optionalStrings" : ["foo"]
}
The exact error is:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Class java.lang.String not subtype of [collection type; class java.util.List, contains [simple type, class com.foo.MyPojo]];
nested exception is com.fasterxml.jackson.databind.JsonMappingException: Class java.lang.String not subtype of [collection type; class java.util.List, contains [simple type, class com.foo.MyPojo]]`
The context is spring boot, which uses ObjectMapper.
All jackson libraries at latest version, which is currently 2.10.3.
Sample unremarkable json that should work:
{
"plainString": "foo",
"optionalString": "foo",
"plainStrings": [
"foo"
],
"optionalStrings": [
"foo"
]
}
To be clear, deserializing to Optional<String> optionalString works as expected, ie:
- missing from payload ->
null - in payload with null value ->
Optional.empty() - in payload with a value ->
Optional.of(value)
But when the field is an Optional List type, deserialization explodes.
Is there a work around? Do I need to an annotation or configuration?