简体   繁体   中英

Ignore jackson deserialization if the data and model field are not of the same type

How would I ignore Jackson deserialization if the data to be deserialized and model field are not of the same type.

Suppose Foo is the model that I want the data to be deserialized into and data is as given below:

public class Foo{
    private boolean isTrue;
}
{
    "isTrue": "ABC"
}

I know about @JsonIgnore but I need a better way where Jackson deserializes the data if the data to be deserialized matches the model data type on its own.

Maybe you could use custom deserializer. To find out if the data can be deserialized to some type might be tricky otherwise than just trying to deserialize and if it fails then return some default value. Bad thing is that each type needs a deserializer of its own but we it can be abstracted to some extent.

public static abstract class SafeDeserializer<T> extends JsonDeserializer<T> {
    protected abstract Class<T> getClassT();

    // This is just fine for any other than primitives.
    // Primitives like boolean cannot be set to null so there is a need for 
    // some default value, so override.
    protected T getDefaultValue() {
        return null;
    }

    @Override
    public T deserialize(JsonParser p, DeserializationContext ctxt)
                            throws IOException, JsonProcessingException {
        try {
            return (T) ctxt.readValue(p, getClassT());
        } catch (MismatchedInputException e) {
            return getDefaultValue();
        }
    }
}

Now extending this to handle a bad boolean would be something like:

public static class SafeBooleanDeserializer extends SafeDeserializer<Boolean> {
    @Getter
    private final Class<Boolean> classT = Boolean.class;

    // This is needed only because your class has primitive boolean
    // If it was a boxed Boolean null would be fine.
    @Override
    protected Boolean getDefaultValue() {
        return false;
    }
}

Rest is quite straigthforward, annotate your field like:

@JsonDeserialize(using = SafeBooleanDeserializer.class)
private boolean isTrue;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM