【问题标题】:Jackson reading all numbers as BigDecimal杰克逊将所有数字读取为 BigDecimal
【发布时间】:2017-06-07 09:08:21
【问题描述】:

我们正在使用 Jackson 从文件系统中读取 json 并将其解析到 POJO。

POJO

String name;
Map<String,Object> map;
getters/setters

阅读

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
Pojo obj = mapper.readValue(jsonFile, Pojo.class);

问题

当我们在 json(地图部分)中有数字时,它们会被转换为 IntegerDouble。我们希望我们所有的数字(小数和整数)作为类型 BigDecimal 所以我尝试使用

mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

但这仅适用于十进制数。没有可用于将整数转换为 BigDecimal 的功能。

问题

  1. 我们是否有任何内置功能可以让 ObjectMapper 将所有数字读取到 BigDecimal?
  2. 如果我需要编写自定义序列化程序,我需要为整个类编写它还是可以为 Map 字段编写它?

【问题讨论】:

  • USE_BIG_INTEGER_FOR_INTS 是否足够接近?
  • 嗨,感谢您的快速响应,我尝试使用它,但它会将数字转换为 BgInteger,因为我们需要 BigDecimal。
  • 确实如此。出于兴趣,您为什么需要它们是 BigDecimal?
  • 当然,但如果它们实际上是整数值,那么BigInteger 就足以处理任意位数。
  • 我的意思是:为什么有些值是BigDecimal 而有些是BigInteger,这有什么关系?

标签: java json jackson


【解决方案1】:

您可以使用包含自定义JsonDeserializerObjectMapper 注册Module。您不需要自己制作,因为 Jackson Databind 提供了 BigDecimalDeserializer,但您还需要做一件事才能使其正常工作。

因为 BigDecimalDeserializer 带有 @JacksonStdImpl 注释,Jackson 不允许你直接使用它,因为初始化代码(我目前不同意)specifically checks for this annotation and disallows it。因为这个反序列化器不是final,所以你可以通过创建一个匿名子类来解决这个问题而无需复制粘贴。

最后会是这个样子

Module module = new SimpleModule();
module.addDeserializer(Number.class, new NumberDeserializers.BigDecimalDeserializer() {});
new ObjectMapper().registerModule(module).readValue("{}", Map.class);

【讨论】:

    【解决方案2】:

    尝试将:BigDecimal:[dps] 放在您的json 中。例如:

    {
      "MY_BIG_D:BigDecimal:0" : 3
    }
    

    其中 dps = 小数位。

    【讨论】:

    • 这有什么帮助?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 2015-07-28
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    相关资源
    最近更新 更多