# FastJSON与Jackson序列化的区别——踩过的一百个坑

FastJSON与Jackson序列化的区别——踩过的一百个坑

问题背景

在与第三方API对接时,涉及到层级嵌套过深,接口提供加密方法可能会出现差异,导致传输后校验sign不正确,因此可能会需要自己这边先对嵌套的List进行Json化,再加密,之后进行传输,但今天遇到的一个问题比较邪门。无论怎么传都得到接口返回,api sign 不正确,仔细检查了方法,发现问题只能在Json时出现问题,由于我使用的是内部封装JsonUtils,所使用Jackson实现。

先说结论:特别是在处理大数字(如雪花算法生成的ID)时,FastJSON和Jackson的默认行为存在显著差异,可能导致接口调用失败。
在这里插入图片描述

现象描述

考虑以下示例数据:

class Order {
    private Long id = 1912712976293294081L;
    // 其他字段...
}

使用不同库序列化的结果:

// FastJSON结果
{"id": 1912712976293294081}

// Jackson结果
{"id": "1912712976293294081"}

原因分析

  1. FastJSON:

    • 默认保持数字类型
    • 对大数字采用原样输出
    • 不做特殊处理
  2. Jackson:

    • 默认将大数字转换为字符串
    • 这样做是为了防止JavaScript处理大数字时的精度损失
    • JavaScript的Number类型最大安全整数是2^53-1

解决方案

1. 修改Jackson配置

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        // 禁用将大数字转换为字符串
        mapper.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false);
        return mapper;
    }
}

2. 使用注解方式

public class Order {
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
}

3. 全局配置序列化器

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> builder.serializerByType(Long.class, ToStringSerializer.instance)
                               .serializerByType(Long.TYPE, ToStringSerializer.instance);
    }
}

最佳实践建议

  1. API文档优先

    • 仔细阅读第三方API文档
    • 确认字段类型要求
    • 进行接口测试验证
  2. 统一序列化策略

    • 项目中统一使用一种序列化库
    • 保持配置一致性
    • 做好文档说明
  3. 测试验证

    • 编写单元测试
    • 使用Postman等工具验证
    • 记录关键数据日志

示例代码

// 调试代码
@Slf4j
public class JsonTest {
    public void compareJsonOutput() {
        Order order = new Order();
        
        // FastJSON输出
        String fastJsonStr = JSONObject.toJSONString(order);
        log.info("FastJSON结果: {}", fastJsonStr);
        
        // Jackson输出
        String jacksonStr = objectMapper.writeValueAsString(order);
        log.info("Jackson结果: {}", jacksonStr);
    }
}

常见陷阱

  1. 前端JavaScript处理大数字精度问题
  2. 不同序列化库默认行为差异
  3. 第三方API对数据格式的严格要求

总结

  1. FastJSON和Jackson在处理Long类型时有不同的默认行为
  2. 需要根据具体场景选择合适的序列化策略
  3. 统一项目中的序列化配置很重要
  4. 做好测试和日志记录

相关链接

标签

Java JSON FastJSON Jackson 序列化 Long类型 大数字处理


最近有个想法,想把自己踩过的坑全都搬到线上来,专门做一个系列,有时候可能真就是一个小细节,就要排查很久,但是如果但凡有一点印象,或许就能加快排查步骤,大家可以支持点赞下。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值