Springboot返回给前端的Long类型数据失去精度

Springboot返回给前端的Long类型数据失去精度

最近在写的一个项目后台 用到的实体类主键ID是用idworker生成的Long类型唯一id
由于之前一直用字符串id 所以突然发现Long类型数据通过JSON传到前端发生精度丢失

精度丢失

javascript 的 Number 类型最大长度是17位;
mysql 使用bigint 类型长度是20位;
我用到的idworker生成的id是19位的 刚好最后两位会凑整 也就是精度给我整没了

解决办法

我在项目用到的是mybatis-plus
下面列一些我的解决办法

把字段解析成字符串

用到了JsonFormat注解让对象属性在经过spring解析成JSON时直接转化成字符串
在要转的字段上加

	/**
	 * 用户ID
	 */
	@TableId(value = "user_id", type = IdType.INPUT)
	@JsonFormat(shape = JsonFormat.Shape.STRING)//转化成string传到前端
	private Long userId;

这种方法我觉的不太好用 兄弟们实体类多的话那得一个一个加好麻烦

全局配置 把数字类型全部转化成字符串

在application.yml配置文件里加

spring:
  jackson:
    generator:
      write-numbers-as-strings: true

这个方法我也不推荐 把所有数字都转成字符串了 分页之类要用到的integer啥的都不太方便

Jackson全局转化long类型为String

新建一个配置类
具体代码如下

@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;
	}
}

这个方式我很推荐 只拦截对应的类型 兄弟们可以用起来

还有一些小细节想提一嘴
Long.class对应的是long的包装类Long,Long.TYPE对应的是基本数据类型long类型
如果你想拦截Long包装类类型的字段,不拦截基本数据类型long字段
除了在这个配置类里拦截外,你还得看你实体类的get方法返回值类型是什么,
因为Jackson转化是用get方法来获取值的,这里的拦截也是看get方法

举个例子

private Long userId;

public long getUserId(){
	return this.userId
}

这样你的这个字段就没有被拦截还是数字到前端
因为你拦截的是Long类型 get方法返回的是long类型

最后

希望这篇博客可以给你带来帮助

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值