I’m trying to deserialize a YearWeek from threetenextra library from a json scalar string using jackson with the following mix in:
import org.threeten.extra.YearWeek;
import com.fasterxml.jackson.annotation.JsonCreator;
public class YearWeekMixIn {
@JsonCreator
public static YearWeek parse(String value) {
return YearWeek.parse(value);
}
}
But the following test fails:
public class YearWeekMixInTest {
public record Foo(YearWeek yearWeek) {}
@Test
public void foo() throws JsonMappingException, JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(YearWeek.class, YearWeekMixIn.class);
objectMapper.readValue("{"yearWeek": "2011-W01"}", Foo.class);
}
}
I get the following exception:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of
org.threeten.extra.YearWeek
(no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value (‘2011-W01’)
What is missing in the mix in to let jackson know it should use the annotated method in the mixin for deserialization?
2
Answers
Jackson’s mixin doesn’t support add outside factory method.
So I think I have three other solutions for you.
https://reachmnadeem.wordpress.com/2016/09/23/jackson-mixin-to-the-rescue/ maybe be help you understand the key point
the doc’s key is the 3.
as if the ”target class” had all annotations that the ”mix-in” class has (for purposes of configuring serialization / deserialization)
in the mixin, it associate the annotations(it’s not as the entry as identifier), it like aspect-oriented, but actutally it isn’t aspect-oriented ehence, it just attach extra meta data to the target class
solution1(kept all method signature consistent)
solution2(using StdConverter, and there is no need to config ObjectMapper)
solution3(using StdDeserializer)
MixIns are used to inject annotations into methods that already exist in the class being mixed into, not to provide new implementations and not to provide custom factory methods. The signature of the mixed in method needs to match exactly with the method in the actual class. In this case, the signatures don’t match as the
parse
method inYearWeek
class accepts aCharSequence
whereas the MixIn’sparse
method accepts aString
. Matching the method signatures would make this work. The MixIn class could look something like the below: