SpringBoot基于Jackson解决Long型长度丢失问题

 更新时间:2025年08月21日 09:18:36   作者:future romance  
本文主要介绍了SpringBoot基于Jackson解决Long型长度丢失问题,通过自定义Jackson ObjectMapper子类添加String序列化器,并在SpringMVC配置中注册该转换器,使ID在JSON传输中保持完整,与数据库数据一致

问题背景

JavaScript能处理的数据精度有限,长度一旦超过17位就会发生长度丢失。因此,id值在被序列化为JSON时经常会有后几位与原数据匹配不上的问题。

数据库中的数据

可以发现页面拿到的数据的id值和数据库中的id值最后两位不一致

为了解决该问题,可以将Long型转化为String
可利用jackson的ObjectMapper来实现

解决方法

ObjectMapper(对象转换器),是jackson中的一个类,它实现了java对象到JSON之间的转换(序列化、反序列化)。

当ObjectMapper中固有的序列化器(或反序列化器)不能满足我们的需求时,我们需要自定义一个对象转换器,即创建 ObjectMapper 的子类,为其添加新的序列化器,例如 (Long --> String) 的序列化器

实现步骤

1. 自定义对象转换器,添加序列化器(或反序列化器)

2. 将该对象转换器加入到 SpringMVC 的消息转换器队列中

自定义的对象转换器即为ObjectMapper的子类,为其添加序列化器

/**
 * 对象转换器 ObjectMapper:基于jackson将Java对象转为json(序列化),或者将json转为Java对象(反序列化)
 *
 *          ObjectMapper中固有的序列化器(或反序列化器)可能不能满足我们的需求
 *      因此需要创建 ObjectMapper 的子类,自定义新的序列化器,例如 Long --> String 的序列化器
 *
 */
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 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)   // 实现 Long --> String 的序列化器
                .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)));

        // 对自定义的 simpleModule 进行注册
        this.registerModule(simpleModule);
    }
}

现在已经创建出了自定义的对象转换器,但还无法生效,需要对它进行相关配置

在WebMVC配置类中,重写extendMessageConverters方法,将自定义的对象转换器加入到消息转换器队列中,使其生效

/**
     * 扩展 Spring MVC 的消息转换器
     *
     *      将自定义的对象转换器 JacksonObjectMapper 加入到 SpringMVC 的消息转换器队列中
     *
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器......");

        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();

        messageConverter.setObjectMapper(new JacksonObjectMapper());

        converters.add(0, messageConverter);

    }

再次测试结果如下

可以发现此时页面拿到的id值都已经变成了String,而且与数据库中的id值完全一致

如此,便解决了Long型长度丢失问题

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

相关文章

  • MyBatis使用动态表或列代码解析

    MyBatis使用动态表或列代码解析

    这篇文章主要介绍了MyBatis使用动态表或列代码解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 通过一个map替换字符串中指定的字符变量方法

    通过一个map替换字符串中指定的字符变量方法

    下面小编就为大家带来一篇通过一个map替换字符串中指定的字符变量方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 详解Java编程中线程同步以及定时启动线程的方法

    详解Java编程中线程同步以及定时启动线程的方法

    这篇文章主要介绍了详解Java编程中线程同步以及定时启动线程的方法, 讲到了wait()与notify()方法以及阻塞队列等知识,需要的朋友可以参考下
    2016-01-01
  • Java多线程实现同时输出

    Java多线程实现同时输出

    这篇文章主要介绍了Java多线程实现同时打印的相关资料,需要的朋友可以参考下
    2016-03-03
  • kafka 重新分配partition和调整replica的数量实现

    kafka 重新分配partition和调整replica的数量实现

    当需要提升Kafka集群的性能和负载均衡时,可通过kafka-reassign-partitions.sh命令手动重新分配Partition,增加节点后,可以将Topic的Partition的Leader节点均匀分布,以提高写入和消费速度,感兴趣的可以了解一下
    2022-03-03
  • Mybatis Plus 字段为空值时执行更新方法未更新解决方案

    Mybatis Plus 字段为空值时执行更新方法未更新解决方案

    这篇文章主要介绍了Mybatis Plus 字段为空值时执行更新方法未更新解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Spring Cloud Gateway 服务网关的部署与使用详细讲解

    Spring Cloud Gateway 服务网关的部署与使用详细讲解

    这篇文章主要介绍了Spring Cloud Gateway 服务网关的部署与使用详细介绍,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • Spring Boot腾讯云短信申请与使用示例

    Spring Boot腾讯云短信申请与使用示例

    这篇文章主要介绍了Spring Boot腾讯云短信申请与使用,本文通过实例代码图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • JAVA中的函数式接口Function和BiFunction详解

    JAVA中的函数式接口Function和BiFunction详解

    这篇文章主要介绍了JAVA中的函数式接口Function和BiFunction详解,JDK的函数式接口都加上了@FunctionalInterface注解进行标识,但是无论是否加上该注解只要接口中只有一个抽象方法,都是函数式接口,需要的朋友可以参考下
    2024-01-01
  • IDEA中SpringBoot项目的yml多环境配置方式

    IDEA中SpringBoot项目的yml多环境配置方式

    这篇文章主要介绍了IDEA中SpringBoot项目的yml多环境配置,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-10-10

最新评论