强制 spring boot jackson 反序列化器使用 BigDecimal

问题描述 投票:0回答:3

我遇到了一个问题,杰克逊将数值反序列化为我无法预测的任意类型。例如,如果有人传递值“14”,jackson 会将其实例化为

Integer
。然而,如果有人传递值“14.01”,那么 Jackson 会将其实例化为
Double
。这是一个问题,因为我有一个自定义反序列化器(
@JsonCreator
),它抛出异常,因为我无法预测将字段转换为 BigDecimal。理想情况下,杰克逊会把一切都变成
BigDecimal

我发现一篇文章表明杰克逊可能有能力做这样的事情。 在 Jackson 中将 JSON 反序列化为通用映射,强制所有 JSON 浮点为十进制或字符串

但是,我不知道如何访问隐藏在 Spring Boot 中的映射器对象以运行适当的方法

mapper.enable()

这是解串器的片段:

@JsonCreator
public OptionTransaction(Map<String,Object> jsonObj){  
    Map<String,Object> jsonOption = (Map<String, Object>) jsonObj.get("option");

    Map<String,Object> optionPriceObj = (Map<String, Object>) jsonOption.get("price");
    BigDecimal optionValue = new BigDecimal((Double) optionPriceObj.get("value"));

正如你在上面看到的,

Double
阵容是一个问题,因为杰克逊有时不喂双打。有谁知道一种简单的方法让 Jackson 始终输出 BigDecimals,甚至只是字符串?

更新:

就将双精度数转换为 BigDecimal 而言,我通过按以下方式修改 application.properties 来完成此操作:

# ===============================
# = DESERIALIZATION CUSTOMIZATION
# ===============================
spring.jackson.deserialization.USE_BIG_DECIMAL_FOR_FLOATS=true
java json spring serialization jackson
3个回答
6
投票
@JsonCreator
public OptionTransaction(Map<String,Object> jsonObj){  
    Map<String,Object> jsonOption = (Map<String, Object>) jsonObj.get("option");

    Map<String,Object> optionPriceObj = (Map<String, Object>) jsonOption.get("price");
    BigDecimal optionValue = new BigDecimal((Double) optionPriceObj.get("value"));
}

..

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

OptionTransaction transaction = mapper.readValue(jsonString, OptionTransaction.class);

https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features


0
投票
@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        return builder
                .modules(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES), new JavaTimeModule())
                .deserializers( new NumberDeserializers.BigDecimalDeserializer())
                .featuresToEnable(MapperFeature.AUTO_DETECT_CREATORS)
                .build();
    }
}

0
投票

Spring Boot 配置中的设置非常简单:

spring:
  jackson:
    deserialization:
      use-big-decimal-for-floats: true

在 OpenAPI 规范中使用(用于生成 MyClass { BigDecimal id; }:

MyClass:
  type: object
  properties:
    id:
      type: number
      example: 666.66
© www.soinside.com 2019 - 2024. All rights reserved.