后端Long类型传到前端精度丢失的正确解决方式
2023-09-14 09:02:29 时间
原因:前端js对Long类型支持的精度不够,导致后端使用的Long传到前端丢失精度,比如现在分布式id生成算法“雪花算法”在使用中就会出现问题。
解决方式:
1、后端的Long类型的id转用String存储,不推荐,失去了其Long类型本身的意义。
2、在Long类型字段上使用注解标明序列化方式,代码量不大的情况可以考虑
@JsonSerialize(using = ToStringSerializer.class) private Long id;
3、实现WebMvcConfigurer接口,重写configureMessageConverters方法
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); jackson2HttpMessageConverter.setObjectMapper(objectMapper); converters.add(jackson2HttpMessageConverter); converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); }
但是这种方式需要开启@EnableWebMvc注解。
开启这个注解意味着springboot的mvc等自动配置失效,所以这个方式实际上也是不可取的。
类似的还有继承WebMvcConfigurationSupport类,也会导致一些配置失效https://www.cnblogs.com/asker009/p/12752716.html
类似不可取的还有重写HttpMessageConverters,这会覆盖其他的类型转换。
@Configuration public class LongToJsonConfig { public LongToJsonConfig() { } @Bean public HttpMessageConverters customConverters() { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); jackson2HttpMessageConverter.setObjectMapper(objectMapper); return new HttpMessageConverters(new HttpMessageConverter[]{jackson2HttpMessageConverter}); } }
以上方式基本都不可取。
4、重新注册ObjectMapper的Long类型序列化方式,推荐使用,暂时没发现问题。
@Configuration public class LongClassMessageConverter implements InitializingBean { @Resource ObjectMapper objectMapper; private SimpleModule getSimpleModule() { SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); // 暂时放弃对小long的转换,约定与前端交互数据时,大Long全部转换成字符串 // simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); return simpleModule; } @Override public void afterPropertiesSet() { SimpleModule simpleModule = getSimpleModule(); objectMapper.registerModule(simpleModule); } }
5、重新构建Jackson序列化方式,与第四点类似的解决方式,推荐使用。
@Configuration public class JacksonConfig { /** * Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题 */ @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() { @Override public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) { jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance); jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance); // jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance); } }; return cunstomizer; } }
6、以上方式针对springboot默认的Jackson序列化,fastjson等其他json组件类似处理。
7、如果前端自身涉及到Long类型的计算,那么需要前端自己实现Long类型支持,参考:https://github.com/dcodeIO/long.js
相关文章
- 后端转前端的小老弟突然收割大厂offer,真相竟然是
- java websocket client_前端和后端哪个累
- 【说站】文案微信小程序源码独立版+前端
- 这到底是前端还是后端Bug
- web navigator_前端如何传参数为一个对象
- vue双向绑定数组和对象有什么区别_后端接收前端json数据
- 前端js手写面试题汇总(二)
- 前端后端都可以用的精美json数据查看神器
- Web前端 ---入门教学
- 前端脚手架构建实践
- 用Echarts实现前端表格引用从属关系可视化
- 如何在前端大屏展示中实现真正的自助
- CSS 前端头条二月周刊(第1周)
- 批量上传GPT知识库,前端elementui的upload上传组件,后端Golang的上传接口实现