码迷,mamicode.com
首页 > 其他好文 > 详细

后端Long类型传到前端精度丢失的正确解决方式

时间:2020-05-14 15:39:59      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:配置   雪花   style   convert   tom   bean   ack   object   ast   

原因:前端js对Long类型支持的精度不够,导致后端使用的Long传到前端丢失精度,比如现在分布式id生成算法“雪花算法”在使用中就会出现问题。

解决方式:

1、后端的Long类型的id转用String存储,不推荐,失去了其Long类型本身的意义。

2、在Long类型字段上使用注解标明序列化方式,代码量不大的情况可以考虑

    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;

3、实现WebMvcConfigurer接口,重写configureMessageConverters方法

  @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter =
                new MappingJackson2HttpMessageConverter();

        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        converters.add(jackson2HttpMessageConverter);
        converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }

但是这种方式需要开启@EnableWebMvc注解。

开启这个注解意味着springboot的mvc等自动配置失效,所以这个方式实际上也是不可取的。

类似的还有继承WebMvcConfigurationSupport类,也会导致一些配置失效https://www.cnblogs.com/asker009/p/12752716.html

类似不可取的还有重写HttpMessageConverters,这会覆盖其他的类型转换。

 

 
@Configuration
public class LongToJsonConfig {
    public LongToJsonConfig() {
    }
 
    @Bean
    public HttpMessageConverters customConverters() {
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        return new HttpMessageConverters(new HttpMessageConverter[]{jackson2HttpMessageConverter});
    }
}

 

以上方式基本都不可取。

 

 

4、重新注册ObjectMapper的Long类型序列化方式,推荐使用,暂时没发现问题。

 

@Configuration
public class LongClassMessageConverter implements InitializingBean {

    @Resource
    ObjectMapper objectMapper;

    private SimpleModule getSimpleModule() {

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        // 暂时放弃对小long的转换,约定与前端交互数据时,大Long全部转换成字符串
//        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return simpleModule;
    }


    @Override
    public void afterPropertiesSet() {
        SimpleModule simpleModule = getSimpleModule();
        objectMapper.registerModule(simpleModule);
    }
}

 

5、重新构建Jackson序列化方式,与第四点类似的解决方式,推荐使用。

@Configuration
public class JacksonConfig {
    /**
     * Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() {
            @Override
            public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
                jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance);
                jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
//                jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);
            }
        };
        return cunstomizer;
    }
}

6、以上方式针对springboot默认的Jackson序列化,fastjson等其他json组件类似处理。

7、如果前端自身涉及到Long类型的计算,那么需要前端自己实现Long类型支持,参考:https://github.com/dcodeIO/long.js

 

后端Long类型传到前端精度丢失的正确解决方式

标签:配置   雪花   style   convert   tom   bean   ack   object   ast   

原文地址:https://www.cnblogs.com/asker009/p/12888388.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!