Hi, I'm using a delegating deserializer with java.util.Date as the delegate type and my class 'CustomDate' as the target type. I want to apply this deserializer to a constructor argument in conjunction with a ValueInstantiator. I got it to work but I would like to know if there is a simpler way.
Delegating deserializer with java.util.Date as delegate type:
public class CustomDateDeserializer extends StdDelegatingDeserializer<CustomDate>
{
public CustomDateDeserializer() {
super(new StdConverter<Date, CustomDate>() { ... });
}
public CustomDateDeserializer(Converter<?, CustomDate> converter,
JavaType delegateType,
JsonDeserializer<?> delegateDeserializer) { ... }
}
// other content omitted
}
POJO:
@JsonValueInstantiator(value = TestInstantiator.class)
public class Test{
public Test(CustomDate customDate) {
}
// rest omitted
}
ValueInstantiator:
public class TestInstantiator extends StdValueInstantiator
{
public boolean canCreateFromObjectWith() {
return true;
}
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
CreatorProperty customDate = new CreatorProperty(new PropertyName("customDate"),
config.constructType(CustomDate.class), null, null,
null, null, 0, null, PropertyMetadata.STD_REQUIRED)
.withValueDeserializer(new CustomDateDeserializer());
return new CreatorProperty[] { customDate };
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException, JsonProcessingException {
return new Test((CustomDate) args[0]);
}
}
Creating a Test instance fails with a NPE because the values for
_delegateType and
_delegateDeserializer in StdDelegatingDeserializer are null. These values are set by Jackson when deserializing a property of type CustomDate but are not set automatically when deserializing the constructor argument.
To resolve this, I have to use a fully initialized delegating deserializer in TestInstantiator
new CustomDateDeserializer(new StdConverter<Date, CustomDate>() { ... },
config.constructType(Date.class),
new DateDeserializers.DateDeserializer());
Is this the correct way to do it or is there way to set up the CreatorProperty such that Jackson will set the delegateType and delegateDeserializer as it does for properties?
I set up a module with
addDeserializer(CustomDate.class, new CustomDateDeserializer());
but Jackson does not associate the constructor argument with the custom deserializer and that's why I have to specify the deserializer explicitly for CreatorProperty.
Thanks.