-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Is your feature request related to a problem? Please describe.
I am currently trying to deserialize a structure with a generic field that has an external type property, where the type property is always present, but the actual property may be absent, in which case it should just use a custom NullValueProvider.
The json can either look like this:
{
"type": "inner-implementation",
"value": {
"foo": "bar"
}
}Or like this, in which case value should use the NullValueProvider:
{
"type": "inner-implementation"
}The outer type looks like this:
public class Wrapper<I extends Inner> {
@JsonTypeInfo(use = Id.NAME, include = As.EXTERNAL_PROPERTY)
private I value;
public Wrapper(@JsonProperty(value = "value", required = true) I value) {
this.value = value;
}
}And the inner types all implement this interface:
@JsonSubTypes({
@Type(InnerImplementation.class),
})
public interface Inner {}With an implementation of the inner type looking like this:
@JsonTypeName("inner-implementation")
@JsonDeserialize(using = InnerImplementationDeserializer.class)
public class InnerImplementation implements Inner {
@Nullable
private String foo;
public InnerImplementation(@Nullable String foo) {
this.foo = foo;
}
}Each implementation of Inner also has a deserializer which implements the getNullValue method:
class InnerImplementationDeserializer extends StdNodeBasedDeserializer<InnerImplementation> {
protected InnerImplementationDeserializer() {
super(TypeFactory.defaultInstance().constructType(InnerImplementation.class));
}
@Override
public InnerImplementation convert(JsonNode root, DeserializationContext ctxt) throws IOException {
JsonNode foo = root.get("foo");
return new InnerImplementation(foo != null ? foo.textValue() : null);
}
@Override
public InnerImplementation getNullValue(DeserializationContext ctxt) throws JsonMappingException {
return new InnerImplementation(null);
}
}I have also disabled FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY.
The first snippet deserializes without problems, and when I remove required = true from the value property, the second snippet deserializes with Wrapper#value being null. With required = true however, a com.fasterxml.jackson.databind.exc.MismatchedInputException is thrown.
The exception originates from this part of the jackson databind codebase.
Describe the solution you'd like
In the linked snippet of jackson code, it would in my opinion be appropriate to use the custom NullValueProviders if FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY is disabled.
Usage example
The feature would work like shown above, however depending on how reasonable this approach generally is, the option FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY could be disabled by default.
Additional context
The underlying WRAPPER_ARRAY property used in the background by EXTERNAL_PROPERTY was already changed to support this behaviour: #2467