我遇到了一个问题,jackson 将数值反序列化为我无法预测的任意类型。例如,如果有人传递值“14”,jackson 会将其实例化为一个Integer
。但是,如果有人传递值“14.01”,则 jackson 会将其实例化为 Double
。这是一个问题,因为我有一个自定义反序列化器 (@JsonCreator
),它会抛出异常,因为我无法预测地将字段转换为 BigDecimal。理想情况下,jackson 会把所有东西都变成 BigDecimal
。
我找到了一个帖子,暗示 Jackson 可能有能力做这样的事情。 Deserialize JSON into a generic map, forcing all JSON floats into Decimal or String, in Jackson
但是,我不知道如何访问隐藏在 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 有时不提供 double 。有谁知道让 jackson 始终输出 BigDecimals 或什至只输出字符串的简单方法?
更新:
就将 double 转换为 BigDecimal 而言,我通过按以下方式修改 application.properties 来完成此操作:
# ===============================
# = DESERIALIZATION CUSTOMIZATION
# ===============================
spring.jackson.deserialization.USE_BIG_DECIMAL_FOR_FLOATS=true
最佳答案
@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
关于java - 强制 spring boot jackson 解串器使用 BigDecimal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40214080/