SpringBoot jackson 精度处理问题解决

 更新时间:2024年10月11日 10:10:36   作者:酒醉的胡铁  
由于JavaScript处理的最大数值限制,较大的雪花ID在JS中容易溢出,为解决此问题,可在SpringMVC或SpringBoot中使用@RequestBody注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

问题说明

因为js能处理的最大值和最小值分别是

private static final long MAX_SAFE_INTEGER = 9007199254740991L;
private static final long MIN_SAFE_INTEGER = -9007199254740991L;

所以我们的雪花id很容易就超出了这个范围,所以要转换为字符串做适配
例如:1692419165819899402 就会变成1692419165819800000

解决方案

入参

在Spring MVC或Spring Boot中,可以使用@RequestBody将字符串类型的JSON字段映射到Java中的long类型字段,只要字符串内容是一个有效的long值。Spring的Jackson库会自动处理这个转换。需要注意处理可能的转换异常,以确保应用的健壮性。

返回需要配置处理器

实体类字段就可以定义为Long类型了

package com.platform.paycenter.config;

import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.platform.paycenter.handler.BigNumberSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * jackson 配置
 *
 * @author Lion Li
 */
@Slf4j
@Configuration
public class JacksonConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> {
            // 全局配置序列化返回 JSON 处理
            JavaTimeModule javaTimeModule = new JavaTimeModule();
            javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
            javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
            javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
            javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
            javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
            builder.modules(javaTimeModule);
            builder.timeZone(TimeZone.getDefault());
            log.info("初始化 jackson 配置");
        };
    }

}

package com.platform.paycenter.handler;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;

import java.io.IOException;

/**
 * 超出 JS 最大最小值 处理
 *
 * @author Lion Li
 */
@JacksonStdImpl
public class BigNumberSerializer extends NumberSerializer {

    /**
     * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
     */
    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
    private static final long MIN_SAFE_INTEGER = -9007199254740991L;

    /**
     * 提供实例
     */
    public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);

    public BigNumberSerializer(Class<? extends Number> rawType) {
        super(rawType);
    }

    @Override
    public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 超出范围 序列化位字符串
        if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
            super.serialize(value, gen, provider);
        } else {
            gen.writeString(value.toString());
        }
    }
}

到此这篇关于SpringBoot jackson 精度处理问题解决的文章就介绍到这了,更多相关SpringBoot jackson 精度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中字符串常见题之String相关讲解

    Java中字符串常见题之String相关讲解

    今天小编就为大家分享一篇关于Java中字符串常见题之String相关讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • IDEA 集成log4j将SQL语句打印在控制台上的实现操作

    IDEA 集成log4j将SQL语句打印在控制台上的实现操作

    这篇文章主要介绍了IDEA 集成log4j将SQL语句打印在控制台上的实现操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java反射使用的详细介绍(最新推荐)

    Java反射使用的详细介绍(最新推荐)

    这篇文章主要介绍了Java反射使用的详细介绍,反射的第一步都是先得到编译后的Class类对象,然后就可以得到Class的全部成分,本文结合实例代码详细讲解,需要的朋友可以参考下
    2023-02-02
  • Spring实战之清除缓存操作示例

    Spring实战之清除缓存操作示例

    这篇文章主要介绍了Spring实战之清除缓存操作,结合实例形式详细分析了spring清除缓存操作具体步骤、配置、领域模型及相关使用技巧,需要的朋友可以参考下
    2020-01-01
  • Java之while与do-while循环的用法详解

    Java之while与do-while循环的用法详解

    在上一篇文章中,给大家讲解了循环的概念,并重点给大家讲解了for循环的使用。但在Java中,除了for循环之外,还有while、do-while、foreach等循环形式。这篇文章给大家讲解while循环的使用
    2023-05-05
  • mybatis-plus 关于savebatch,saveorupdatebatch遇到的坑及解决办法

    mybatis-plus 关于savebatch,saveorupdatebatch遇到的坑及解决办法

    本文主要介绍了mybatis-plus 关于savebatch,saveorupdatebatch遇到的坑及解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Springboot工具类StringUtils使用教程

    Springboot工具类StringUtils使用教程

    这篇文章主要介绍了Springboot内置的工具类之StringUtils的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • jvm调优常用命令行工具详解

    jvm调优常用命令行工具详解

    这篇文章主要介绍了jvm调优常用命令行工具的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • SpringBoot实现微服务通信的多种方式

    SpringBoot实现微服务通信的多种方式

    微服务通信是指在分布式系统中,各个微服务之间进行数据交互和通信的过程,今天我们将探讨在Spring Boot中实现微服务通信的多种方式,文章通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • java计算自幂数和水仙花数

    java计算自幂数和水仙花数

    对于一个正整数而言,长度是n,如果它的各位上的数字的n次方之和正好等于它本身,那么我们称这样的数为自幂数,下面使用JAVA实现这个方法
    2014-03-03

最新评论