踩坑日记(将Long类型转换成String类型引发的问题)

一. 前提

  1.    线上有一张表,主见id原来使用的是自增id。但是有一个新的业务,在做这个业务的时候,这个id被赋值为雪花算法。致使这个表的主见id值特别大。
  2.   线上有很多业务进行修改的时候,都是通过此表的id进行修改。突然,有人反馈说功能无法使用。这个时候我们立马进行排查,发现我们返回给前端id的值发生了四舍五入的情况。
  3.  后续通过网上查找,发现是说因为Long类型的数值太多,超过了前端js的显示长度,所以就会出现精度丢失的情况,需要将Long类型转换成String类型才不会精度丢失

二 . 解决办法

        解决办法我们采取了全局配置,在序列化的时候将Long转换成String。如下

package cn.lili.common.config;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

/**
 * 返回Long转换为String
 *
 *
 */
public class JacksonMapper extends ObjectMapper {

    public JacksonMapper() {
        super();
        this.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        this.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true);
        this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        simpleModule.addSerializer(long.class, ToStringSerializer.instance);
        registerModule(simpleModule);

    }


}
package cn.lili.common.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
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.WebMvcConfigurer;

import java.util.List;

@Configuration
public class StringWebConfig implements WebMvcConfigurer {

    @Autowired
    private HttpMessageConverters httpMessageConverters;

    /**
     * MappingJackson2HttpMessageConverter 实现了HttpMessageConverter 接口,
     * httpMessageConverters.getConverters() 返回的对象里包含了MappingJackson2HttpMessageConverter
     * @return
     */
    @Bean
    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
        return new MappingJackson2HttpMessageConverter(new JacksonMapper());
    }


    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.addAll(httpMessageConverters.getConverters());
    }

}

通过如上两个全局配置,在进行序列化的时候会自动将Long类型转换成String类型。问题得到成功的解决...............但是也埋下了一个坑。

三.踩坑

一开始说有问题的功能是得到了解决,返回给前端的值是正确的了。但是引发了另外一个问题,因为我们将Long类型转换成了String类型,页面上面有一些数据是经过前端进行运算的。所以转换类型成功后那么原本的运算 1+1 = 2 ,就变成了 "1" + "1" = 11 。如下图,就是错误的实力。相信看到这里大家就都悟了
原本的运算变成了字符串拼接了。导致页面上的很多数据显示有问题了。不过还是偷懒了,不应该让前端去进行运算的


四.另外一种解决办法

在返回的vo里面增对字段加上注解,即可解决问题。但是这种就是冗余了,每此返回这个主键id都要添加注解,目前为了不影响其他功能,只能先加上此注解

五.教训

全局的配置尽量要测试完成才能发布,不然就会像我这样,一个bug改成另外一个bug,哈哈哈

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值