ObjectMapper不一致地映射BigDecimal

时间:2019-01-02 03:58:58

标签: spring-boot jackson

我在Spring Boot应用程序中为JSON中的BigDecimals使用了自定义序列化器/反序列化器。所有浮点/双精度值都映射为BigDecimals,并且序列化器/反序列化器确保BigDecimal的小数位数至少为2。

作为示例,我在单元测试中具有以下内容来创建ObjectMapper

private ObjectMapper getObjectMapper() {
    Jackson2ObjectMapperBuilderCustomizer customizer =
    jacksonObjectMapperBuilder -> {
        jacksonObjectMapperBuilder.featuresToEnable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
        jacksonObjectMapperBuilder.serializerByType(BigDecimal.class, new BigDecimalSerializer(BigDecimal.class));
        jacksonObjectMapperBuilder.deserializerByType(BigDecimal.class, new BigDecimalDeserializer());
    };

    Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
    customizer.customize(builder);

    ObjectMapper objectMapper = builder.build();
    objectMapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
    return objectMapper;
}

然后我将进行以下单元测试:

@Test
public void testCustomOM() {
    ObjectMapper om = getObjectMapper();
    ObjectNode rootNode = om.createObjectNode();
    rootNode.put("balance", new BigDecimal(37D));
    BigDecimal fromBigDecimal = om.convertValue(rootNode.get("balance"), BigDecimal.class);
    Map map = om.convertValue(rootNode, Map.class);
    BigDecimal fromMap = (BigDecimal) map.get("balance");
    assertEquals(2, fromBigDecimal.scale()); // Success
    assertEquals(2, fromMap.scale()); // Assert fails 
}

BigDecimal序列化器

public class BigDecimalSerializer extends StdSerializer<BigDecimal> {

    public BigDecimalSerializer(Class<BigDecimal> t) {
        super(t);
    }

    @Override
    public void serialize(BigDecimal bigDecimal, JsonGenerator generator, SerializerProvider provider) throws IOException {
        generator.writeNumber(setScale(bigDecimal));
    }

    private BigDecimal setScale(BigDecimal bigDecimal) {
        if (bigDecimal.scale() < 2) {
            return bigDecimal.setScale(2, RoundingMode.HALF_EVEN);
        }
        return bigDecimal;
    }
}

和BigDecimalDeserializer

public class BigDecimalDeserializer extends NumberDeserializers.BigDecimalDeserializer {

    @Override
    public BigDecimal deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        return setScale(super.deserialize(parser, context));
    }

    private BigDecimal setScale(BigDecimal bigDecimal) {
        if (bigDecimal.scale() < 2) {
            return bigDecimal.setScale(2, RoundingMode.HALF_EVEN);
        }
        return bigDecimal;
    }
}

当我运行测试时,从转换JsonNode得到的BigDecimal的比例为2,但从Map得到的比例为0。因此,似乎没有使用我在转换为a时定义的BigDecimalDeserializer。地图。

有没有办法让Jackson持续使用此解串器?

0 个答案:

没有答案