Long类型雪花算法ID返回前端后三位精度缺失问题解决

目录

    • 一、问题描述
    • 二、问题复现
      • 1.Maven依赖
      • 2.application.yml 配置
      • 3.DemoController.java
      • 4.snowflakePage.html 页面
      • 5.DemoControllerAdvice.java 监听
      • 6.问题复现
    • 三、原因分析
    • 四、问题解决
      • 方案一
      • 方案二

一、问题描述

Java 后端使用雪花算法生成 Long 类型的主键 ID,在返回前端后,会出现后三位精度丢失的问题。

在这里插入图片描述

在这里插入图片描述

我们写一个 ControllerAdvice 打印一下返回结果看下:

在这里插入图片描述

我们可以看到返回结果是没有问题的,但是返回到前端就会丢失两位精度

二、问题复现

这里主要描述问题的复现过程和代码,不需要的可以直接跳过。

1.Maven依赖

<!-- Hutool,用于生成雪花算法ID -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency><!-- Thymeleaf,用于展示页面 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.application.yml 配置

server:port: 8080spring:mvc:view:prefix: /templates/suffix: .html

3.DemoController.java

import cn.hutool.core.util.IdUtil;
import com.demo.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** <p> @Title DemoController* <p> @Description 测试Controller** @author ACGkaka* @date 2023/4/24 18:02*/
@Slf4j
@Controller
@RequestMapping("/demo")
public class DemoController {@GetMapping("/snowflakePage")public String snowflakePage() {return "snowflakePage";}@GetMapping("/snowflakeId")@ResponseBodypublic Result<Object> snowflakeId() {return Result.succeed().setData(IdUtil.getSnowflakeNextId());}
}

4.snowflakePage.html 页面

页面文件在 resources/templates/ 路径下。

在这里插入图片描述

<!DOCTYPE html>
<html>
<head><title>调用接口并打印返回值</title>
</head>
<body>
<button onclick="getSnowflakeId()">调用接口</button>
<script>function getSnowflakeId() {fetch('/demo/snowflakeId').then(response => response.json()).then(data => {console.log(data.data);document.body.innerHTML += `<p>${data.data}</p>`;}).catch(error => console.log(error));}
</script>
</body>
</html>

5.DemoControllerAdvice.java 监听

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/*** <p> @Title DemoControllerAdvice* <p> @Description Controller增强** @author ACGkaka* @date 2023/4/25 21:07*/
@ControllerAdvice
public class DemoControllerAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter methodParameter, Class aClass) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {System.out.println("body is: " + body);return body;}
}

6.问题复现

请求地址:http://localhost:8080/demo/snowflakePage

在这里插入图片描述

在这里插入图片描述

精度丢失问题复现,下面我们来分析下导致问题的原因。

三、原因分析

  • 后端返回:1703327682407702528
  • 前端接收:1703327682407702500

这是因为 JS 是弱语言,前端接收数字类型参数为 number最大接受长度为 16 位超出长度则会丢失精度。而 JavaLong 类型长度是 19 位,所以传输到前端的后三位精度丢失。

解决问题的思路:把 Java 中 Long 类型转换为 String 类型返回给前端。

四、问题解决

方案一

将所有 ID 使用 String 类型存储,缺点是字符串做 ID 查询效率比较低

方案二

使用注解、配置类,改变序列化过程。

注解方式,适用于 pojo 的 id 属性上。

import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;/*** 主键*/
@TableId
@JsonSerialize(using = ToStringSerializer.class)
private Long id;

配置类方式,适用于全局配置。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;@Configuration
public class JacksonConfig {@Bean@Primary@ConditionalOnMissingBean(ObjectMapper.class)public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){ObjectMapper objectMapper = builder.createXmlMapper(false).build();// 全局配置序修改列化返回 Json 处理方案SimpleModule simpleModule = new SimpleModule();// Json Long --> StringsimpleModule.addSerializer(Long.class, ToStringSerializer.instance);objectMapper.registerModule(simpleModule);return objectMapper;}
}

根据问题复现代码,再次请求地址:http://localhost:8080/demo/snowflakePage

在这里插入图片描述

在这里插入图片描述

精度丢失问题已修复。

整理完毕,完结撒花~ 🌻





参考地址:

1.解决雪花算法生成的ID传输前端后精度丢失,https://blog.csdn.net/weixin_48841931/article/details/127966871

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/81318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速学会搭建微信小程序的基础架构

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 基础架构 构建界面 引入 uni-ui 组件库 组件自动引入 配置TS类型 状态管理 持久化 数据交互 请…

最小二乘法

Least Square Method 1、相关的矩阵公式2、线性回归3、最小二乘法3.1、损失函数&#xff08;Loss Function&#xff09;3.2、多维空间的损失函数3.3、解析法求解3.4、梯度下降法求解 1、相关的矩阵公式 P r e c o n d i t i o n : ξ ∈ R n , A ∈ R n ∗ n i : σ A ξ σ ξ…

leetcode 332. Reconstruct Itinerary(重构行程)

有一些票tickets, tickets[ i ] [from, to], 每个出发到达城市名字都是3个大写英文字母&#xff0c; 同一个出发城市时&#xff0c;优先去字母顺序较小的到达城市。 必须先从“JFK”出发。 每个ticket必须用且只用一次&#xff0c;所有ticket一定会形成至少一个有效的行程&…

Pandas 数据变形和模型分析

数据概念 数据比对 在本练习中&#xff0c;我们使用灵活的比较技术对不同的DataFrame进行比较 import pandas as pd import randomrandom.seed(123) list1 [[A]*3,[B]*5,[C]*7] charlist [x for sublist in list1 for x in sublist] random.shuffle(charlist) ser1 pd.Se…

【JAVA-Day21】序列化和反序列化,学会Java的编解码方法

标题序列化和反序列化&#xff0c;学会Java的编解码方法 序列化和反序列化&#xff0c;学会Java的编解码方法摘要引言一、什么是序列化1.1 序列化的过程 二、什么是反序列化2.1 反序列化的过程 三、为什么要进行序列化和反序列化3.1 主要目的3.2 应用场景 四、总结参考资料 博主…

Springboot 实践(18)Nacos配置中心参数自动刷新测试

前文讲解了Nacos 2.2.3配置中心的服务端的下载安装&#xff0c;和springboot整合nacos的客户端。Springboot整合nacos关键在于使用的jar版本要匹配&#xff0c;文中使用版本如下&#xff1a; ☆ springboot版本: 2.1.5.RELEASE ☆ spring cloud版本 Greenwich.RELEASE ☆ sp…

辅助驾驶功能开发-功能规范篇(21)-4-XP行泊一体方案功能规范

XPilot Parking 自动泊车系统 • 超级自动泊车辅助(Super AutoParking Assist)、语音控制泊车辅助(Autoparking with Speech) - 产品定义 超级自动泊车辅助是⼀个增强的自动泊车辅助系统。在超级自动泊车辅助系统中,识别车位将会变得实时可见, 并且不可泊入的⻋位也将…

如何在 Excel 中计算日期之间的天数

计算两个日期之间的天数是 Excel中的常见操作。无论您是规划项目时间表、跟踪时间还是分析一段时间内的趋势&#xff0c;了解如何在 Excel 中查找日期之间的天数都可以提供强大的日期计算功能。 幸运的是&#xff0c;Excel 提供了多种简单的方法来获取两个日期之间的天数。继续…

数据可视化

一、Flask #通过访问路径&#xff0c;获取用户的字符串参数 app.route(/user/<name>) def welcome(name):return "你好&#xff0c;%s"%nameapp.route(/user/<int:id>) def welcome2(id):return "你好&#xff0c;%d号的会员"%id能够自动根据…

【初阶数据结构】树(tree)的基本概念——C语言

目录 一、树&#xff08;tree&#xff09; 1.1树的概念及结构 1.2树的相关概念 1.3树的表示 1.4树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二、二叉树的概念及结构 2.1二叉树的概念 2.2现实中真正的二叉树 2.3特殊的二叉树 2.4二叉树的性质…

字符集详解

一、为什么乱码&#xff1f; 所有的乱码实质上都是因为字符集选择错误造成的。 流在读取时&#xff0c;编码使用不当也会乱码。 二、什么是字符集&#xff1f; 字符是各种文字和符号的统称&#xff0c;包括各个国家的文字&#xff0c;标点符号&#xff0c;表情等等。字符集…

spring seccurity OAuth 2.0授权服务器工作流程

一、客户端配置&#xff1a;在configure(ClientDetailsServiceConfigurer clients)方法中&#xff0c;配置了一个客户端&#xff0c;包括客户端标识符、客户端秘密、授权类型、授权范围和令牌有效期等信息。这个客户端表示某个应用程序或服务&#xff0c;它将向授权服务器请求访…

MFC主框架和视类PreCreateWindow()函数学习

在VC生成的单文档应用程序中&#xff0c;主框架类和视类均具有PreCreateWindow函数&#xff1b; 从名字可知&#xff0c;可在此函数中添加一些代码&#xff0c;来控制窗口显示后的效果&#xff1b; 并且它有注释说明&#xff0c; Modify the Window class or styles here by…

Bash脚本学习:AWK, SED

1. AWK AWK 是一种编程语言&#xff0c;设计用于处理文件或数据流中基于文本的数据&#xff0c;或者使用 shell 管道。 可以将 awk 与 shell 脚本结合使用或直接在 shell 提示符下使用。 以上展示使用AWK分别打印第一个位置变量和第二个位置变量。 建立一个文档 csvtest.cs…

设计模式:单例模式

目录 什么是单例模式为什么使用单例模式常见的单例写法1. 懒汉式&#xff08;Lazy Initialization&#xff09;2. 双重检查锁定&#xff08;Double-Checked Locking&#xff09;3. 饿汉式&#xff08;Eager Initialization&#xff09;4. 枚举实现单例 总结 什么是单例模式 单…

AI深度学习-卷积神经网络000

文章目录 前言1.什么是深度学习2.语义分割与实例分割概述3.什么是卷积&#xff1f;4.Unet网络 前言 本栏目&#xff0c;主要为深度学习保姆教程。 主要通过B站视频整理而来&#xff1a; 深度学习保姆级教学 Unet语义分割视觉三维重建算法 1.什么是深度学习 深度学习保姆级教…

Scapy 解析 pcap 文件从HTTP流量中提取图片

Scapy 解析 pcap 文件从HTTP流量中提取图片 前言一、网络环境示例二、嗅探流量示例三、pcap 文件处理最后参考 ​ 作者&#xff1a;高玉涵 ​ 时间&#xff1a;2023.9.17 10:25 ​ 环境&#xff1a;Linux kali 5.15.0-kali3-amd64&#xff0c;Python 3.11.4&#xff0c;scapy…

【OpenSSL】VC编译OpenSSL

VC编译OpenSSL 编译工具准备编译OpenSSL建立Hello World工程创建VS工程 编译工具准备 安装好Visual Studio。安装Perl, 主要是用来生成nmake的。准备好汇编语言编译工具nasm,并添加到path路径。下载好Open SSL源代码。 编译OpenSSL 安装Perl,并加入到path路径&#xff0c;检验…

HTML 学习笔记(基础)

它是超文本标记语言&#xff0c;由一大堆约定俗成的标签组成&#xff0c;而其标签里一般又有一些属性值可以设置。 W3C标准&#xff1a;网页主要三大部分 结构&#xff1a;HTML表现&#xff1a;CSS行为&#xff1a;JavaScript <!DOCTYPE html> <html lang"zh-…

SkyWalking快速上手(二)——架构剖析1

文章目录 介绍架构概述一、Agent组件介绍Agent的配置配置参数详解service_namesample_n_per_3_secsnamespacecollector.backend_service Agent的工作原理 二、Collector组件什么是Collector组件?Collector组件的配置配置Collector组件示例 总结 介绍 SkyWalking是一个开源的分…