【问题标题】:Jackson: Is there a way to ignore 0/1 on Boolean deserialization?Jackson:有没有办法在布尔反序列化时忽略 0/1?
【发布时间】:2019-09-03 20:26:05
【问题描述】:

我有一个带有Boolean 属性的JSON 对象,在反序列化期间只需要允许truefalse

任何不同于truefalse 的值都应该引发异常。

我该怎么做?


例如:

有效的json:

{
  "id":1,
  "isValid":true
}

无效的 json:

{
  "id":1,
  "isValid":1
}

更新

我尝试了@Michał Ziober 的建议,效果很好。

当我正在实现一个 Spring 应用程序(使用 Webflux)时,我只需要以不同的方式进行配置。我在这里发布我所做的:

  • 创建一个从DelegatingWebFluxConfiguration 扩展的配置类
  • 覆盖configureHttpMessageCodecs 方法设置属性ObjectMapper
@Configuration
public class JacksonConfig extends DelegatingWebFluxConfiguration {

    @Override
    protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        configurer.defaultCodecs()
                .jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper));
    }
}

【问题讨论】:

  • 您是使用硬编码还是使用第三方包进行反序列化?如果您使用的是第三方包,那么newtonsoft您使用的是什么包?
  • @i-medina 你有没有想过编写自己的 JsonDeserializer?
  • @StéphaneJeandeaux 是的,我想过。但我想知道是否有比这更简单的方法,比如 Jackson 注释或配置。
  • @xTwisteDx 我正在使用 Jackson 2.9.8

标签: java json jackson deserialization jackson-databind


【解决方案1】:

您需要禁用ALLOW_COERCION_OF_SCALARS 功能:

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS);

        System.out.println(mapper.readValue(jsonFile, Pojo.class));
    }
}

class Pojo {

    private int id;
    private Boolean isValid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Boolean getIsValid() {
        return isValid;
    }

    public void setIsValid(Boolean valid) {
        isValid = valid;
    }

    @Override
    public String toString() {
        return "Pojo{" +
                "id=" + id +
                ", isValid=" + isValid +
                '}';
    }
}

上面的代码打印:

线程“main”中的异常 com.fasterxml.jackson.databind.exc.MismatchedInputException: 不能 类型 java.lang.Boolean 的强制编号 (1)(启用 MapperFeature.ALLOW_COERCION_OF_SCALARS 允许)在 [来源: (文件);行:3,列:14](通过参考链: Pojo["isValid"]) 在 com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)

【讨论】:

  • 在spring-boot项目中可以在application.properties中设置:spring.jackson.mapper.allow-coercion-of-scalars=false
【解决方案2】:

嗯,这不是针对任何情况的实现,但它可能适合您:

public class TestBooleanDeserializer extends JsonDeserializer<Boolean> {

  @Override
  public Boolean deserialize(JsonParser jsonParser, DeserializationContext context)
      throws IOException, JsonProcessingException {
    String str = jsonParser.getText();    
    boolean val = Boolean.valueOf(str);
    if (!val && Objects.nonNull(str) && !Objects.equals("false", str.toLowerCase())) {
      throw new RuntimeException("invalid JSON");
    }
    return val;
  }

}

因为Boolean.valueOfjava.lang.Boolean# 检查的结果

public static boolean parseBoolean(String s) {
    return ((s != null) && s.equalsIgnoreCase("true"));
}

在这里:boolean val = Boolean.valueOf(str); 您将检查它是否为 true 值。如果没有,您应该检查是null 还是falseif (!val &amp;&amp; Objects.nonNull(str) &amp;&amp; !Objects.equals("false", str.toLowerCase())) 如果不是,您可以根据需要抛出异常。否则你会返回一个布尔值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    相关资源
    最近更新 更多