我在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持续使用此解串器?