后端使用雪花发号器生成的long型作为业务主键,在数据库与后端中,均表现正常,然后返回前端时,出现了精度不准确的问题。
数据库数据
后端获取数据正常
返回前端后数据精度丢失
以前总是不理解,为什么后端提供了这么多数据类型,但是前辈们设计系统的时候都喜欢全员字符串的设计。自己设计开发写的越来越多之后慢慢还是了解了string的安全之处。文本就是最纯粹也最final的东西。
比如这个long型,在前端无法精确表现。这是js中num精度的问题。
那么要怎么解决这种问题呢?
首先,考虑沿袭前辈们的做法,替换成string返回前端。
或者,要求前端支持long型。
第二种做法对我来说太不安全了。
所以,我还是考虑替换成string返回前端吧。泪流满面。
先看下转换结果:
long型用string返回
作为文本,它已经不存在精度问题了。
那么是怎么做的呢?
直接上代码:
/**
* *****************************************************
* Copyright (C) 2020 bytedance.com. All Rights Reserved
* This file is part of bytedance EA project.
* Unauthorized copy of this file, via any medium is strictly prohibited.
* Proprietary and Confidential.
* ****************************************************
**/
package com.hekiraku.gemini.aop.converters;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.math.BigInteger;
import java.util.List;
/**
* 全局类型转换器
* 需要configuration的注解,把它当作一个配置类;
* 需要继承 WebMvcConfigurationSupport ,把配置装配进去
*/
@Configuration
public class MyConverters extends WebMvcConfigurationSupport {
//重写jackson的转换器方法,添加自定义的规则
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
//如果属性为空""或者null都不序列化,返回的json中没有这个字段,对移动端更省流量
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
SimpleModule simpleModule = new SimpleModule();
//配置Long型转化为String的规则
simpleModule.addSerializer(Long.class, new ToStringSerializer());
simpleModule.addSerializer(Long.TYPE, new ToStringSerializer());
//配置BigInteger型转化为String的规则
simpleModule.addSerializer(BigInteger.class, new ToStringSerializer());
objectMapper.registerModule(simpleModule);
converter.setObjectMapper(objectMapper);
converters.add(converter);
}
}