这几天前后端联调,遇到一个诡异的问题。前端请求后端提供的详情接口得到用户的 Id 与其它数据。然后前端又把这个 Id与修改的数据内容一同传回后端的修改接口。结果前端反馈死活修改不了。

然后各种 debug 查日志,发现详情接口返回给前端的与前端调用修改接口传回的 Id 不一致。

然后一查发现是 js 的精度问题,原以为 js 只是浮点型会有精度问题,没想到长整型也会出现。因为是语言的限制,前端要解决这个问题,还是很吃力的。所以只能在后端在传 json 的时候把 long 全部转成 string 类型。

然后问题又来了,因为项目已写了差不多了。太多地方用了 long 类型,改基础类的字段类型是不可能了。于是想在对象转 json 的时候能否统一处理。

因为使用的是 spring boot 框架,而 spring boot 默认的 json 框架的Jackson。就是找了一下,果然 jackson 有一个可以自定义的类型转换器机制。直接上代码↓

  • json 转换器
    JsonLong2StrConverter

    public class JsonLong2StrConverter extends StdSerializer<Long> {
    
      public JsonLong2StrConverter() {
        super(Long.class);
      }
    
      @Override
      public void serialize(Long value, JsonGenerator gen, SerializerProvider provider)
          throws IOException {
    
        gen.writeString(value.toString());
      }
    }
  • 使用配置
    JsonConf

    @Configuration
    @EnableWebMvc
    public class JsonConf extends WebMvcConfigurerAdapter {
    
      @Override
      public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter(
            new Jackson2ObjectMapperBuilder()
    //            .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
                .serializationInclusion(
                    Include.NON_NULL)
                .serializerByType(Long.class, new JsonLong2StrConverter())
                .serializerByType(Long.TYPE, new JsonLong2StrConverter()).build()));
      }
    
    }

这样 spring boot 在转换 json 时,发现是 Long 类型就直接转成 String 类型,也就是加个单引号。

参考:
Spring boot 配置自定义Json类型转换

本文地址 https://blog.coder4j.cn/posts/6bfa638e/