后端如何处理前端id精度丢失的问题

问题的场景是

当前端调用后端接口时,如果后台返回的ID值比较大(例如雪花算法生成的ID),在JavaScript中处理的时候会出现精度丢失的问题。为解决这个问题,可以将ID转化为字符串类型,也可以通过前端框架或组件库进行处理。

解决这个问题,有以下几种思路:

  1. 将后端返回的 ID 值转化为字符串类型。这是一个简单而且可行的方案,如果业务允许使用字符串类型的 ID。可以通过接口或者中间件等方式,将后端返回的长整型 ID 值转化为字符串类型,这样前端就可以安全处理这个 ID 了。
  2. 通过前端框架处理。可以使用一些前端框架,如 Vue、React 等,来处理这个问题。这些框架中通常会提供 BigNumber(高精度数)这样的类库,支持对于大整数的精确处理。
  3. 把 ID 值分段传输。可以将 ID 分为高低位表示,通过两个数字来传输 ID 值。这种方案需要后端和前端协同设计,不易于实现,但可以解决此问题。
  4. 通过前端组件库处理。一些优秀的前端组件库中,也可能会集成处理 Big Integer 类型的组件,例如 element-ui 中就有 support-big-number 组件用于处理超大数据的问题。

总之,解决此问题的方法有很多,具体选择哪一种方案要根据业务需求和当前技术栈来确定。

如果真的需要让后端解决,在不修改实体类数据类型的基础上,我们可以使用消息转换器来实现。

消息转换器是 Spring Framework 中常用的特性之一,用于实现请求和响应的自动转换。Spring Boot 默认使用了 Jackson 模块作为消息转换器,即通过使用 Jackson 库将请求和响应中的 JSON 数据自动转换为实体类对象,或将实体类对象转换为 JSON 数据。在这个场景下,我们可以自定义一个消息转换器,使用其将后端返回的 ID 值转化为字符串类型,然后再响应给前端。

自定义消息转换器代码示例

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 = 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)
                .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)));

        //添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

这段代码是一个 Spring MVC 的消息转换器配置。Spring MVC 中的消息转换器用于将不同的呈现形式(如 JSON、XML 等)的数据转换为 Java 对象和将 Java 对象转换为不同的呈现形式。在代码中,由于我们需要使用 JSON 数据格式进行数据交互,所以需要配置一个 JSON 数据转换器。

具体实现方式如下:

1、扩展 Spring MVC 的消息转换器。
2、创建一个 MappingJackson2HttpMessageConverter 对象。
3、设置 ObjectMapper 对象,使用 JacksonObjectMapper 实例作为对象转换器,即使用 Jackson 序列化库将 Java 对象转换为 JSON。

4、将该转换器对象追加到 Spring MVC 框架的消息转换器接口 List<HttpMessageConverter<?>> converters 集合的开头位置。

需要注意的是,这段代码中继承自 WebMvcConfigurationSupport 类,而不是继承自 WebMvcConfigurerAdapter 类。因为在 Spring Framework 5.0 版本之后,WebMvcConfigurerAdapter 已经被标记为过时,建议开发者继承 WebMvcConfigurationSupport 类来进行 Spring MVC 的配置。

代码示例

public class WebMvcConfig extends WebMvcConfigurationSupport {

/**
* @Description: 消息转换
* @Author: Mr.Lin
* @Date: 2023/6/4
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    log.info("扩展消息转换器...");
    //创建消息转换器对象
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    //设置对象转换器,底层使用Jackson 将Java对象转为json
    messageConverter.setObjectMapper(new JacksonObjectMapper());
    //将上面的消息转换器对象追加到mvc框架的转换器集合中
    converters.add(0,messageConverter);
  }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值