雪花算法精度丢失问题了解:

如图:数据库中 风清扬 对应的ID为 1420038345634918401

观察控制台输出的SQL发现页面传递过来的员工id的值和数据库中的id值不一致,这是怎么回事呢?

在分页查询时,服务端会将返回的R对象进行json序列化,转换为json格式的数据,而员工的ID是一个Long类型的数据,而且是一个长度为 19 位的长整型数据, 该数据返回给前端是没有问题的。

那么具体的问题出现在哪儿呢?

问题实际上, 就出现在前端JS中, js在对长度较长的长整型数据进行处理时, 会损失精度, 从而导致提交的id和数据库中的id不一致。 这里,我们也可以做一个简单的测试,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script>alert(1420038345634918401);</script>
</head>
<body>
</body>
</html>

解决方案:

要想解决这个问题,也很简单,我们只需要让js处理的ID数据类型为字符串类型即可, 这样就不会损失精度了。我们只需要让分页查询返回的json格式数据库中, long类型的属性, 不直接转换为数字类型, 转换为字符串类型就可以解决这个问题了 。下面提供了三种解决方案:
一般情况下全局就可以解决,但是有些特别业务需求就需要使用自定义可以使用第一种方法加第三种全局方案一同使用,局部优先级高于全局。

第一种:通过注解形式解决(局部)

@JsonSerialize()注释,用于通过附加到“getter”方法或字段或值类来配置序列化方面。

注解参数:

 @JsonSerialize(using=MySerializer.class, // using优先级要高于as和typingas=MySubClass.class,// as优先级要高于typingtyping=JsonSerialize.Typing.STATIC)

转换类也可以自己实现,已类型转换为例代码如下:

/*** 自定义序列化器 将Long类型数据转成String*/
public class Long2StringSerializer extends JsonSerializer<Long> {@Overridepublic void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {if(value!=null){gen.writeString(value.toString());}}
}
//实体类
public class User{@JsonSerialize(using= Long2StringSerializer .class)//使用自己实现的类型转换private Long id;private String userName;private String password;}

第二种:通过重写WebMvcConfigurationSupport里的消息转换器方法实现(全局)

具体实现步骤:

  1. 提供对象转换器JacksonObjectMapper,基于Jackson进行Java对象到json数据的转换(资料中已经提供,直接复制到项目中使用)
  2. 在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换

@Configuration
public class AllConfig extends WebMvcConfigurationSupport {/*** 扩展消息转换器*  目的: 主要是告诉jackson 转化JavaBean对象成json字符串的时候,具体的一些类型要转化成什么类型*     比如:  long 类型  ---> String类型* @param converters*/@Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {//1. 创建自己的映射消息转换器 jackson 转化JavaBean成json字符串的转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//2. 把我们定义好的映射规则对象,丢到上面的转换器里面converter.setObjectMapper(new JacksonObjectMapper());//3. 把我们定义好的这个消息转换器,丢到集合里面去converters.add(0,converter);}
}
/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]* * 该自定义的对象转换器, 主要指定了, 在进行json数据序列化及反序列化时, LocalDateTime、LocalDate、LocalTime的处理方式, 以及BigInteger及Long类型数据,直接转换为字符串。*/
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();//收到未知属性时不报异常this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);//反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(BigInteger.class, ToStringSerializer.instance).addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));//注册功能模块 例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}

第三种:创建Jackson2ObjectMapperBuilderCustomizer对象

import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;@Configuration
public class JacksonConfig {/*** Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题*/@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() {@Overridepublic void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {//变成字符串jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);}};return cunstomizer;}
}

关于前后端雪花算法Long转String丢失精度问题相关推荐

  1. java 有穷自动机_Java实现雪花算法(snowflake)

    本文主要介绍了Java实现雪花算法(snowflake),分享给大家,具体如下: 简单描述 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一 ...

  2. long 雪花算法_雪花算法(snowflake)

    简单描述 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序.注意,41位时间截不是存储当前时间的时间截, ...

  3. java雪花_Java实现雪花算法(snowflake)

    本文主要介绍了Java实现雪花算法(snowflake),分享给大家,具体如下: 简单描述 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一 ...

  4. Springboot+爬虫+推荐算法+前后端分离实现小说推荐系统

    如何针对互联网各大小说阅读网站的小说数据进行实时采集更新,建立自己的小说资源库,针对海量的小说数据开展标签处理特征分析,利用推荐算法完成针对用户的个性化阅读推荐? 基于以上问题,本次小说推荐系统,建设 ...

  5. 前后端分离最佳实践:搭建一个复习算法题的网站ReviseCode(一)

    前言:很多人学完SSM就直接学SpringBoot,几乎没有试过整合SSM框架,导致仅仅是学会了SpringBoot使用,并不知道为什么是这样配置.另一方面,有的人整合了SSM框架,并且配置完后完成了 ...

  6. Java接口long类型精度丢失,解决前后端交互Long类型精度丢失问题

    雪花算法ID,对应的后端Long类型,前端number类型,它们的精度不一样,导致精度丢失 现象 雪花算法得到的ID较长,传到前端后,精度丢失 库中:23754851322302474 后端:2375 ...

  7. 解决前后端交互Long类型精度丢失的问题

    雪花算法ID,对应的后端Long类型,前端number类型,它们的精度不一样,导致精度丢失 文章目录 一.现象与分析 1.1. 现象 1.2. 分析 二.解决方案 2.1. 方法一单个注解 2.2. ...

  8. 雪花算法:分布式唯一 ID 生成利器

    无论是在分布式系统中的 ID 生成,还是在业务系统中请求流水号这一类唯一编号的生成,都是软件开发人员经常会面临的一场景.而雪花算法便是这些场景的一个解决方案. 以分布式 ID 为例,它的生成往往会在唯 ...

  9. 2021年数据库课设该怎么做?一个超市管理系统,简单的前后端分离项目,带你从概要设计走到项目发布!(Vue.js+SpringBoot+MybatisPlus)

    由于本文格式原来是word,所以文中有些格式不太对.如果这篇文章对你有帮助,麻烦点赞评论一下谢谢!源码和word文档可私聊领取~ 目录 一.相关技术介绍 1.1 RDBMS: 1.2应用程序开发环境: ...

最新文章

  1. 零基础全方位学习java的方法
  2. 华为服务器HBA卡在哪个位置,服务器hba 设置
  3. 安防业内人士对云存储未来的发展充满信心
  4. awk sed (1)====积累取ip以及sed 查找替换
  5. Lisp和前缀表示法入门
  6. influxdb无法实现关联表_双汇:从棘手的InfluxDB+Redis到TDengine
  7. SpringMVC4返回json
  8. java 程序执行原理
  9. python相机标定
  10. ipsec和nat穿越
  11. 计算机网络断开后怎么连接,电脑网络断开怎样重新连接
  12. 极客爱情 2.4 | 和程序员男友过节是这样的
  13. HDFS容错性设计有哪些?
  14. 系统集成---合同法、著作权法、招标投标实施条例+政府采购法实施条例
  15. JavaFx教程-03JavaFX Application的生命周期
  16. 重庆html5全景,用pano2vr 转swf 全景图
  17. 【民生】2011,骗子仍在行动
  18. AJAX框架简笔画风景简单,海南风景简笔画超简单
  19. 推荐六款逆天好用的黑科技微信小程序,手机内存再小也可以任性耍
  20. 微积分Z2 J2 典型函数

热门文章

  1. 网店分类图片生成软件
  2. c语言小游戏-飞机大战
  3. fibonacci斐波那契数列详解 递归求Fn非递归求Fn求n最近的斐波那契数
  4. android 神器 自动连接手机软件,安卓手机必备的4款神器黑科技APP!一个比一个厉害,请谨慎使用...
  5. RK3288 USB to Seria(PL2303)converter driver
  6. 谈一谈网络编程学习经验(06-08更新)
  7. Linux下使用route设置路由
  8. 基于C++的简易版《球球大作战》游戏设计
  9. 计算机网络(十三)——路由算法
  10. python读写excel教程_Python新手入门:Excel基本操作(一)