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

news2024/11/18 11:47:00

目录

    • 一、问题描述
    • 二、问题复现
      • 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: 8080

spring:
  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")
    @ResponseBody
    public 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 {

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return true;
    }

    @Override
    public 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 --> String
    simpleModule.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.coloradmin.cn/o/1018266.html

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

相关文章

【Unity】万人同屏, 从入门到放弃之——Entities 1.0.16性能测试

当前测试使用的Entities版本为1.0.16 Unity Entities 1.0.16使用方法&#xff1a; Create a component for the spawner example | Entities | 1.0.16 1. 创建SubScene 2. 在SubScene下创建挂载Authoring脚本&#xff1a; Authoring是MonoBehaviour脚本&#xff0c;主要用来…

网页的快捷方式打开自动全屏--Chrome、Firefox 浏览器相关设置

Firefox 的全屏方式与 Chrome 不同&#xff0c;Chrome 自带全屏模式以及APP模式&#xff0c;通过简单的参数即可设置&#xff0c;而Firefox暂时么有这个功能&#xff0c;Firefox 的全屏功能可以通过全屏插件实现。 全屏模式下&#xff0c;按 F11 不会退出全屏&#xff0c;鼠标…

【微信小程序】文章样式,标题样式,及设置背景~

| background-size 设置背景图片大小。图片可以保有其原有的尺寸&#xff0c;或者拉伸到新的尺寸&#xff0c;或者在保持其原有比例的同时缩放到元素的可用空间的尺寸。 | background-size: cover;适配屏幕大小 文章样式&#xff0c;标题样式&#xff0c;及设置背景~ index.w…

AGV小车、机械臂协同作业实战02-开源opentcs 项目调研

这个项目是从0到1 的一个过程&#xff0c;碰到这种项目给我的第一反应就是先查查有没有轮子&#xff0c;往往站在巨人的肩膀上 事情就会变得简单多了。各种搜索后发现网站这类的项目少之又少&#xff0c;唯一一个值得参考的项目 就是Opentcs 了&#xff0c;而且这个项目最近也在…

echarts-图表(非常规图开发记录)

echarts-图表&#xff08;非常规图开发记录&#xff09; 环形刻度图横向左右柱形图3D饼图渐变柱子-柱状图3D柱状图雷达图动态滚动图-并加图片 以下图表数据源&#xff0c;allData.value 均为如下格式 [{"id": "1","name": "在职在岗",…

企业邮箱功能详解:提升办公效率的多面手

企业邮箱是一种专为企业打造的电子邮件服务&#xff0c;它可以帮助企业提高工作效率、加强内部沟通和保护企业信息安全。本文将介绍企业邮箱的一些主要功能和优势。 一、邮件收发 企业邮箱提供了一个专门的电子邮件账户&#xff0c;员工可以通过这个账户收发工作相关的邮件。相…

基于SSM的校园自助洗衣系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

GIS跟踪监管系统电子围栏

GIS跟踪监管系统电子围栏 &#xff08;1&#xff09;电子围栏展示。① 显示&#xff1a;② 隐藏&#xff1a;&#xff08;2&#xff09;电子围栏修改。① 新增电子围栏。② 修改电子围栏。工具箱&#xff08;1&#xff09;测量。① 测量距离&#xff1a;② 测量面积&#xff1a…

洛科威多功能岩棉板助力节能减碳战略,推动碳达峰目标实现

国家相关部门提出了要“协同推进降碳、减污、扩绿、增长&#xff0c;推进生态优先、节约集约、绿色低碳发展”的总要求&#xff0c;未来相当长的时间里&#xff0c;降碳都将是一项重要工作&#xff0c;节能降碳是实现碳达峰碳中和的有效途径&#xff0c;也是着力解决资源环境约…

基于springboot+vue的企业面试预约管理系统

基于springbootvue的企业面试预约管理系统 预约面试管理系统&#xff0c;可以通过学生&#xff0c;企业角色进行登录 登录后可以查看发布的岗位&#xff0c;发布人&#xff0c;发布时间&#xff0c;面试时间&#xff0c;招聘时间&#xff0c;招聘单位简介等 查看用户管理信息

云组网案例分享

最近遇到了一个客户场景&#xff0c;是个非常典型的跨云组网场景&#xff0c;我们梳理了下这个客户的需求以及我们提供的解决方案&#xff0c;出于保密要求&#xff0c;文章不会涉及任何客户信息。如果您想体验我们的产品&#xff0c;可以登录我们的控制台免费使用&#xff0c;…

【Axure原型素材】扫一扫

今天和粉丝们免费分享扫一扫的原型素材&#xff0c;"扫一扫"是一项常见的移动应用功能&#xff0c;通常通过手机或平板电脑上的摄像头来扫描二维码或条形码以实现各种功能。下面是和大家分享扫一扫的常用素材~~~ 【原型效果】 【Axure原型素材】扫一扫 【原型预览】…

石油天然气工程用热轧型钢

声明 本文是学习GB-T 42678-2023 石油天然气工程用热轧型钢. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了石油天然气工程用热轧型钢的订货内容、牌号表示方法、尺寸、外形、重量、技术要求、 试验方法、检验规则、包装、标志…

springboot日志配置(logback+slf4j配置)

1.为什么要配置日志 故障排查和问题分析&#xff1a; 日志记录允许开发人员和运维人员在系统发生问题或故障时追踪问题的根本原因。通过查看日志文件&#xff0c;他们可以了解系统在特定时间点发生了什么事情&#xff0c;从而更容易定位和解决问题。 性能监控和优化&#xff1a…

YOLOV7改进:在C5模块不同位置添加D-LKA Attention(同时拥有SA注意力和大卷积核的能力)

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点。 3.涨点效果:D-LKA Attention注意力机制,实现有…

有没有一款让人爱不释手的知识库工具?知识库管理工具不难选!

对于企业来说&#xff0c;因为其本身的业务需求、外部各类标准规范的要求、数字化转型趋势带来的便利&#xff0c;使得更多的企业开始自主搭建知识库&#xff0c;开始试图通过知识管理去提升组织的效率和创新能力。 虽然说市面上有不少关于知识笔记的管理工具&#xff0c;比如有…

Android Kotlin 基础详解

1,基础语法 1.1 可变变量与不可变变量 可以多次赋值的变量是可变变量&#xff0c;用关键字var表示&#xff1a; var <标识符> : <类型> <初始化值> 注意&#xff0c;在kotlin中成员变量不会赋默认值&#xff0c;不像java一样&#xff0c;必须手动添加默…

时间复杂度讲解(数据结构)

目录 引言 什么是数据&#xff0c;结构和算法 时间复杂度的概念 如何计算时间复杂度 总结 引言 hello大家好&#xff0c;我是boooooom君家宝。在前期的博客中博主呢对c语言的一些重要知识点进行了讲解&#xff0c;接下来博主的博客内容将为大家呈现的是数据结…

JavaScript:二进制数组【笔记】

二进制数组【ArrayBuffer对象、Type的Array视图和DataView视图】JavaScript操作二进制数据的一个接口。 这些接口原本是和WebGL有关【WebGL是浏览器与显卡之间的通信接口】&#xff0c;为了满足JavaScript与显卡之间大量、实时数据交换&#xff0c;那么JavaScript和显卡之间的…

认识面向对象-PHP8知识详解

面向对象编程&#xff0c;也叫面向对象程序设计&#xff0c;是在面向过程程序设计的基础上发展而来的&#xff0c;它比面向过程编程具有更强的灵活性和扩展性。 它用类、对象、关系、属性等一系列东西来提高编程的效率&#xff0c;其主要的特性是可封装性、可继承性和多态性。…