Fasterxml Jackson automatically converts non-boolean value to a boolean value

谁说胖子不能爱 提交于 2019-12-01 06:34:35

问题


I have a pojo class where one of the flag isControl which is of type Boolean.

When this property gets a non boolean value other than true or false fasterxml jackson automatically converts the input value to true. After debugging for few hours I find out that this is happening in the setter method setIsControl.

I want to pass a custom message if input value for this property is non-boolean. I have written my own annotation to validate the input value for this property and return custom message if its not a boolean value but jackson binds the value before checking my custom validator.

Using jackson version >>> 2.6.3. Any help will be appreciated.

Control.java

    @JsonProperty(required = true)
    @NotNull(message = "isControl cannot be null")
    private Boolean isControl;

    public Boolean getIsControl() {
            return isControl;
    }


    @CheckBoolean(fieldName = "isControl")
    public void setIsControl(Boolean isControl) {
            this.isControl = isControl;
    }

public class BooleanValidator implements ConstraintValidator<CheckBoolean,  Boolean> {

    private String fieldName;

    @Override
    public void initialize(CheckBoolean constraintAnnotation) {
        this.fieldName = constraintAnnotation.fieldName();
    }

    @Override
    public boolean isValid(Boolean value, ConstraintValidatorContext context) {         
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(
                String.format("The control flag %s should be either true or false", fieldName))
                .addConstraintViolation();

        if (value != null) {
            boolean isBoolean;
            if (value instanceof Boolean) {                 
                isBoolean = ((Boolean)value).booleanValue();
                System.out.println("var isBoolean: " +isBoolean);
                return true;
            } else if (value instanceof Boolean && Boolean.FALSE.equals(value)) {
                isBoolean = ((Boolean)value).booleanValue();                    
                return true;
            } else {
                return false;
            }           
        }
return false;
}
}

Exception:


回答1:


There are two ways of doing this assuming that you will map boolean field as Object type as HARDI answered -

1. Customize the setter method -

    public class DTO {
    String key1;
    Object booleanKey;

    public Object getBooleanKey() {
        return booleanKey;
    }

    public void setBooleanKey(Object booleanKey) {
        if (booleanKey instanceof Boolean) {
            this.booleanKey = booleanKey;
        } else {
            // custom code here
        }

    }

    public String getKey1() {
        return key1;
    }

    public void setKey1(String key1) {
        this.key1 = key1;
    }
    }

2. Write Custom Deserializer -

class BooleanKeyDeserializer extends JsonDeserializer<Object> {

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    Object object = p.readValueAs(Object.class);
    if (!(object instanceof Boolean)) {
        // custom code here
    }
    return object;
}
}

Annotate the field for which you want to perform custom deserialization -

class DTO {
String key1;
@JsonDeserialize(using = BooleanKeyDeserializer.class)
Object booleanKey;
//setters getters
}



回答2:


I think this is because the setter sets it as boolean. The below works. In this case, I have taken the boolean as an object in my deserialized class.

public class Json {
    private String key1;
    private Object booleanKey;
    public String getKey1() {
        return key1;
    }
    public void setKey1(String key1) {
        this.key1 = key1;
    }
    public Object getBooleanKey() {
        return booleanKey;
    }
    public void setBooleanKey(Object booleanKey) {
        this.booleanKey = booleanKey;
    }
}

public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

        String jsonString = "{\"key1\" : \"value1\", \"booleanKey\" : true}";

        ObjectMapper mapper = new ObjectMapper();
        Json obj = mapper.readValue(jsonString,Json.class);
        if (obj.getBooleanKey() instanceof Boolean) {
            System.out.println("booleanKey is boolean");
        } else {
            System.out.println("booleanKey is some other beast");
        }


        jsonString = "{\"key1\" : \"value1\", \"booleanKey\" : \"test\"}";
        obj = mapper.readValue(jsonString, Json.class);
        if (obj.getBooleanKey() instanceof Boolean) {
            System.out.println("booleanKey is boolean");
        } else {
            System.out.println("booleanKey is some other beast");
        }
    }


来源:https://stackoverflow.com/questions/40244770/fasterxml-jackson-automatically-converts-non-boolean-value-to-a-boolean-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!