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

问题背景

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


如图,页面通过get请求拿到用户数据

Alt


数据库中的数据
Alt


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

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

解决方法

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

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

实现步骤

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

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



1. 自定义对象转换器,添加序列化器(或反序列化器)
   自定义的对象转换器即为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);
    }
}

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


2. 将该对象转换器加入到 SpringMVC 的消息转换器队列中
   在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型长度丢失问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值