如何处理Long类型精度丢失问题?

news2024/9/23 21:29:34

如何处理Long类型精度丢失问题?_拒绝画大饼的博客-CSDN博客

解决问题:long型数据精度丢失_long精度丢失_YOLO小蜗的博客-CSDN博客

原因分析

在这里插入图片描述


通过观察控制台输出的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数据类型为字符串类型即可, 这样就不会损失精度了。同样, 大家也可以做一个测试:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        alert("1420038345634918401");
    </script>
</head>
<body>
</body>
</html>

那么在我们的业务中, 我们只需要让返回的json格式数据库中, long类型的属性, 不直接转换为数字类型,转换为字符串类型就可以解决这个问题了 , 最终返回的结果为 :

在这里插入图片描述

  • 方法1、使用JsonSerialize注解序列化的时候把Long自动转为String(单个属性)
 /**
     * 订单编号
     */
    //@JsonSerialize(using = ToStringSerializer.class)
    private Long id;

方法2,由于在SpringMVC中, 将Controller方法返回值转换为json对象, 是通过jackson来实现的,涉及到SpringMVC中的一个消息转换器MappingJackson2HttpMessageConverter,所以我们要解决这个问题, 就需要对该消息转换器的功能进行拓展。

具体实现步骤:
1). 提供对象转换器OptimizationObjectMapper ,基于Jackson进行Java对象到json数据的转换
2). 在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换

引入OptimizationObjectMapper
 

package com.hmall.order.config;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:序列化和反序列化时,数据格式指定。
 * 本转换器继承自Jackson中提供的转换核心类ObjectMapper
 * 支持
 *  指定格式的日期时间字符串与LocalDateTime的序列化和反序列化
 *  BigInteger、Long --> String的序列化
 */
@Component
public class OptimizationObjectMapper 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 OptimizationObjectMapper() {
        super();
        // 反序列化特性:反序列化时属性不存在的兼容处理,未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
        this.getDeserializationConfig().withoutFeatures(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)
                // Long --> String,可以解决本案中的问题
                .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);
    }
}

该自定义的对象转换器, 主要指定了, 在进行json数据序列化及反序列化时,LocalDateTime、LocalDate、LocalTime的处理方式, 以及BigInteger及Long类型数据,直接转换为字符串。

在WebMvcConfig中重写方法extendMessageConverters

2 .在WebMvcConfig中重写方法extendMessageConverters
 

package com.hmall.order.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

@Configuration
public class WebMVCConfig extends WebMvcConfigurationSupport {
    /**
     * 扩展mvc框架的消息转换器
     *
     * @param converters 转换器列表集合
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //设置自定义的对象转换器
        converter.setObjectMapper(new OptimizationObjectMapper());
        // 通过设置索引,让自己的转换器放在最前面,否则默认的jackson转换器会在前面,用不上自己配置的转换器
        converters.add(0, converter);
    }
}

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

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

相关文章

Node中的模块引擎EJS模块渲染

1.导入 const ejsrequire("ejs") 2.声明数组 const group["张三","李四","王二","麻子"] 3.EJS实现 let resultejs.render(<ul> <% group.forEach(item>{ %> <li><%item%></li> <% }) …

ionic实现滑动的三种方式

ionic实现滑动的三种方式 在移动端受屏幕大小所限&#xff0c;展示内容很多的时候&#xff0c;就要使部分区域进行滑动。本文展示项目中所有到的几种方式&#xff0c;大家可以看自己的需求选择合适的滑动方式。实现滑动的基本原理&#xff0c;有两个容器A、B,假如A在外层&#…

[element-ui] el-descriptions站位,换行用法

使用element-ui组件el-descriptions element-ui组件el-descriptions官方文档 需要将el-descriptions-item换行用法&#xff1a;使用span &#xff08;1&#xff09;span 代表占位&#xff0c;当span 的值大于 column的值&#xff0c;就会自动换一行 &#xff08;2&#xff0…

通过正则表达式删除包含某个字符串的一整行

正则表达式为&#xff1a;^.*YourString.*\R 以下为NotePad编辑器的操作步骤&#xff1a; 1、CtrlH打开文本编辑器的替换功能 2、将上面的正则表达式复制到"查找目标"文本框 3、"替换为"文本框置为空 4、勾选“正则表达式” 5、点击替换或者全部替换

数据结构-ArrayList

目录 线性表 顺序表 ArrayList ArrayList的使用 ArrayList的构造方法 ArrayList的常用方法 ArrayList的遍历 实现简单的ArrayList 洗牌算法 删除公共字符串问题 杨辉三角 线性表 线性表是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的数据结…

【标准】国家标准GB7713-87(科学论文编写格式)

目 录 1 引言 2 定义 2.1 科学技术报告 2.2 学位论文 2.3 学术论文 3 编写要求 4 编写格式 5 前置部分 5.1 封面 5.2 封二 5.3 题名页 5.4 变异本 5.5 题名 5.6 序或前言 5.7 摘要 5.8 关键词 5.9 目次页 6 主体部分 6.1 格式 6.2 序号 6.3 引言(或绪论)…

如何在没有软件的情况下将 PDF 转换为 PPT(100% 免费)

演示文稿由文字、图片、音频、动画等元素组成&#xff0c;通常用于会议、课堂或演讲中&#xff0c;展示演讲者想要表达的主要内容。如果您遇到重要文档以 PDF 格式存储&#xff0c;但现在需要转换为 PPT 格式的情况&#xff0c;请不要担心。我们本指南的目标是帮助用户将 PDF 转…

BeanFactory和ApplicationContext的入门、关系和继承

BeanFactory快速入门 ApplicationContext快速入门 BeanFactory与ApplicationContext的关系 1)BeanFactory是Spring的早期接口&#xff0c;称为Spring的Bean工厂。ApplicationContext是后期更高级接口&#xff0c;称之为Spring 容器; 2)ApplicationContext在BeanFactory基础上…

路径规划算法:基于瞬态优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于瞬态优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于瞬态优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法瞬态…

充电桩系统的阿里云服务器的配置如何?

两台ecs. 微信公众号 微信小程序 微信商户 Redis mysql netty mqtt 更多信息私信我

【Leetcode】203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextNone): # self.val va…

Apollo、RocketMQ加载顺序问题

在SpringCloudAlibaba框架中&#xff0c;因Nacos配置中心管理权限过于简单&#xff0c;决定用Apollo代替Nacos配置中心&#xff0c;但在启动时&#xff0c;Nacos、Redis等配置读取正常&#xff0c;RocketMQ由于启动过早&#xff0c;无法从Apollo读取自己的服务地址配置。 报错…

基于github制作个人学术网站(主页)

模板 首先找到一个学术模板&#xff0c;fork到远程仓库。academicpages&#xff0c;如果不是很清楚具体的步骤&#xff0c;可以参考保姆级教程。在github上对该网站代码修改不是很方便&#xff0c;肯定是在本地进行更新后push到远程仓库。 本地Git 学会下载和安装就行&#…

读取摄像机的内参和畸变系数并对畸变图像进行去畸变

这个程序的目标是读取摄像机的参数(内参和畸变系数),并对畸变图像进行去畸变操作,然后进行一些特征点和矩形框的绘制。 #include 语句引入所需的库。using namespace std; 和 using namespace cv; 语句是在代码中使用std和opencv命名空间,这样就不用在每次使用这些库的函数…

Bluetooth 开发科普

Bluetooth 开发科普 1、蓝牙协议结构 Controller运行在蓝牙芯片上&#xff0c;host运行在主控上&#xff0c;两芯片通过硬件通信接口&#xff08;uart或usb&#xff09;&#xff0c;进行通信连接&#xff08;HCI&#xff09;。 实际使用中有不同场景&#xff0c;根据场景需求&…

第三章 SSD存储介质:闪存 3.2-3.3

3.2 闪存实战指南 闪存接口有同步异步之分。一般来说&#xff0c;异步传输速率慢&#xff0c;同步传输速率快。 &#xff08;1&#xff09;异步接口没有时钟&#xff0c;每个数据读由一次RE_n信号触发&#xff0c;每个数据写由一次WE_n信号触发。 &#xff08;2&#xff09;同步…

又曝新作!阿里P9再出山,操作性超强的Spring源码实践

如果你看懂了 Spring 源码&#xff0c;再去看 MyBatis、Spring Security 源码&#xff0c;你会发现这些源码都非常容易&#xff0c;稍微瞅几眼就懂了。 然而源码的学习是一个枯燥的过程&#xff0c;源码解读也是一个枯燥的过程&#xff0c;但是一旦你把源码搞懂了&#xff0c;…

远程接口调用工具Feign

JAVA 项目中如何实现接口调用&#xff1f; Httpclient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 U…

C++、QT(GUI)知识库系统

目录 一、项目介绍 二、项目展示 三、源码分享 一、项目介绍 知识库系统 为一些常用知识进行统一储存、管理、更新、检索等功能的系统&#xff0c;整体类似于博客之类的系统。 用户的使用流程&#xff1a; 查看知识&#xff1a;搜索知识关键字 -> 点击查看知识内容 -…

Simulink仿真模块 - Delay

Delay:按固定或可变采样期间延迟输入信号 在仿真库中的位置为:Simulink / Commonly Used Blocks Simulink / Discrete HDL Coder / Commonly Used Blocks HDL Coder / Discrete 模型为: 双击模型打开参数设置界面,如图所示: 说明 Delay 模块会在一段延迟之后再输出模块的…