【问题标题】:Fasterxml Jackson automatically converts non-boolean value to a boolean valueFasterxml Jackson 自动将非布尔值转换为布尔值
【发布时间】:2017-03-07 18:52:15
【问题描述】:

我有一个 pojo 类,其中一个标志 isControl 是布尔类型。

当此属性获得除true or false 以外的非布尔值时,fastxml jackson 会自动将输入值转换为true。经过几个小时的调试,我发现这是在setter方法setIsControl中发生的。

如果此属性的输入值为非布尔值,我想传递自定义消息。我已经编写了自己的注释来验证此属性的输入值,如果它不是布尔值但杰克逊在检查我的自定义验证器之前绑定了该值,则返回自定义消息。

使用杰克逊版本>>> 2.6.3。任何帮助将不胜感激。

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;
}
}

例外:

【问题讨论】:

    标签: java json serialization jackson fasterxml


    【解决方案1】:

    假设您将布尔字段映射为 HARDI 回答的对象类型,有两种方法 -

    1.自定义setter方法 -

        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。编写自定义反序列化器 -

    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;
    }
    }
    

    注释要执行自定义反序列化的字段 -

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

    【讨论】:

    • 只是想知道,这是 Jackson Api 的错误吗?是否在任何最新版本的 jackson api 中都进行了处理,以便我们可以避免编写自定义反序列化?请多多指教。
    • Jackson 2.9 似乎为此实现了一个功能:ALLOW_COERCION_OF_SCALARS
    【解决方案2】:

    我认为这是因为 setter 将其设置为布尔值。下面的作品。在这种情况下,我将布尔值作为反序列化类中的对象。

    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");
            }
        }
    

    【讨论】:

    • 感谢 Hardi 给我指路,因为我需要在很多地方进行此更改,我可以有一些自定义注释,如果它不是布尔值,我可以发送自定义消息吗?请提出建议。
    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 2016-04-27
    • 2012-02-25
    • 2015-02-20
    相关资源
    最近更新 更多