BigDecimal/Long 前后端交互失去精度解决办法

本文主要参考:https://blog.csdn.net/xu622/article/details/84326599   但是个人觉得这个博客里关于问题原因的解释有点问题。


背景

项目测试过程中,测试给我提了一个bug,新增一个BigDecimal类型数据的时候填入   1234567891234567891.12345  然后页面显示为  1234567891234568000 。

纠错

检查过程中,发现数据库保存的确实是正常的,用postman测试接口返回也是正常的。

 

但是发现f12调试里的数据有问题,同样的数据,在response和preview里面居然不一样

最后推测可能是json转对象时出的问题,然后用jquery的JSON.parse测了一下发现,果然是的。

最后的原因参考

解决办法

分为前端处理办法和后端处理办法

前端处理办法

tips:前端处理办法应该可以实现,但是我目前对前端技术不太通,没试过,先放着这供参考吧。

可以使用json-bigint插件来处理 https://github.com/sidorares/json-bigint

后端处理方法

1.类属性直接定义为String类型,如果需要计算的时候再转BigDecimal 。(优点:避免采坑,不必担心精度问题    缺点:可能要经常转换类型)

2.在待转换字段上加  @JsonSerialize(using = ToStringSerializer.class)   

遗留问题

对BigDecima类型的属性进行转换之后发现,数据后尾会多个0,这是因为这个ToStringSerializer.class类直接对该属性进行了toString()操作。

正常来说对BigDecima类型的属性打印都是用   参考

decimalObject.stripTrailingZeros().toPlainString()

所以我们要针对BigDecima类型处理重新写一个专门的子类

public class BigDecimalToStringSerializer extends ToStringSerializer {
    public static final BigDecimalToStringSerializer instance = new BigDecimalToStringSerializer();

    public BigDecimalToStringSerializer() {
        super(Object.class);
    }

    public BigDecimalToStringSerializer(Class<?> handledType) {
        super(handledType);
    }

    @Override
    public boolean isEmpty(SerializerProvider prov, Object value) {
        if (null == value) {
            return true;
        }
        String str = ((BigDecimal) value).stripTrailingZeros().toPlainString();
        return str.isEmpty();
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(((BigDecimal) value).stripTrailingZeros().toPlainString());
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
        return this.createSchemaNode("string", true);
    }
}

最后在需转换字段上加上就解决了

@JsonSerialize(using = BigDecimalToStringSerializer.class)

优化

如果需要全局加的参考

https://cloud.tencent.com/developer/article/1335444

原文地址:https://www.cnblogs.com/qingshan-tang/p/12420852.html