• 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

  • 相关阅读:
    struts2实现的简单的Trie树
    从源码总结struts2命名空间的匹配规则
    Knockout2.x:ko.dataFor()、ko.contextFor()使用
    Reporting Services可選參數設置
    在.net CF中設置DataGrid中列的寬度
    VB.net 簡體繁體轉化代碼
    在SQL語句中獲取錯誤信息
    VS 2005 使用 Crystal report 發生載入報表失敗
    Lazarus一個奇怪的設置
    怎样用wince设备创建快捷方式
  • 原文地址:https://www.cnblogs.com/qingshan-tang/p/12420852.html
Copyright © 2020-2023  润新知