本文主要參考: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)
優化
如果需要全局加的參考