使用FastJSON解析JSON发生异常的踩坑记录

 更新时间:2025年09月08日 09:36:52   作者:tingyu  
这篇文章主要为大家详细介绍了使用FastJSON解析JSON发生异常的问题原因分析以及对应的解决方法,文章的示例代码讲解详细,感兴趣的小伙伴可以了解下

前言

最近在开发电子签名项目时遇到了一个特别头疼的问题,系统在处理JSON数据时突然报错,错误信息看起来很奇怪:syntax error : f。经过一番排查,发现是FastJSON在处理特定数据时的一个坑。今天把这个问题记录下来,希望能帮到遇到类似问题的朋友。

问题现象

系统运行得好好的,突然就报错了:

com.alibaba.fastjson2.JSONException: syntax error : f
at com.alibaba.fastjson2.JSONReaderUTF16.readBoolValue(JSONReaderUTF16.java:6426)
at com.alibaba.fastjson2.JSONReader.read(JSONReader.java:2164)
at com.alibaba.fastjson2.JSON.parse(JSON.java:67)
at com.alibaba.fastjson2.JSON.toJSON(JSON.java:3506)

看到这个错误,第一反应是:什么鬼?JSON格式没问题啊,怎么就解析不了了?

问题代码

出问题的代码很简单,就是想从返回的数据中提取一个字段:

// 这行代码出问题了
com.alibaba.fastjson2.JSONObject contentJson = 
    (com.alibaba.fastjson2.JSONObject) com.alibaba.fastjson2.JSON.toJSON(invoke.getData().getContent());

String edocId = null;
edocId = contentJson.getString("formRecordId");

if (StringUtils.isBlank(edocId)) {
    edocId = contentJson.getString("formRecordCode");
}

数据分析

接口返回的JSON数据看起来完全正常:

{
    "id": 8745074954268373736,
    "startAccountId": -8901286526055593580,
    "generateType": null,
    "prevNodeId": 175688901899730,
    "formRecordId": 6003933439012269528,
    "pcPageParam": null,
    "dealTime": 0,
    "nodeName": "管理员",
    "formRecordCode": "6003933439012269528",
    "extLong1": 0,
    "overdueWorkingShow": null
}

乍一看没什么问题,但仔细观察会发现,formRecordId 的值是一个很大的数字:6003933439012269528

问题根源

经过反复测试和分析,发现问题出在FastJSON处理大数字时的一个坑:

  • 大数字处理问题:当JSON中包含超出JavaScript安全整数范围的数字时,FastJSON在某些情况下会出现解析异常
  • 类型转换问题:直接使用 JSON.toJSON() 方法可能会触发内部的类型推断机制,导致解析错误
  • 字符编码问题:在某些环境下,字符编码也可能影响JSON解析

解决方案

方案一:避免使用 JSON.toJSON()

最直接的解决方法就是改变JSON处理方式:

// 原来的写法(有问题)
com.alibaba.fastjson2.JSONObject contentJson = 
    (com.alibaba.fastjson2.JSONObject) com.alibaba.fastjson2.JSON.toJSON(invoke.getData().getContent());

// 改进后的写法
String contentStr = com.seeyon.boot.util.JsonUtils.toJson(invoke.getData().getContent());
com.alibaba.fastjson2.JSONObject contentJson = com.alibaba.fastjson2.JSON.parseObject(contentStr);

方案二:统一使用Hutool工具类

既然FastJSON容易踩坑,不如换个更稳定的工具:

// 使用Hutool的JSON工具
cn.hutool.json.JSONObject contentJson = new cn.hutool.json.JSONObject(invoke.getData().getContent());
String edocId = contentJson.getStr("formRecordId");
if (StrUtil.isBlank(edocId)) {
    edocId = contentJson.getStr("formRecordCode");
}

方案三:增加异常处理

无论用什么方案,都要加上异常处理,让程序更健壮:

private String invokeGetEdocIdByAffairId(Long affairId) {
    // ... 前面的代码省略
    
    try {
        // 使用更安全的JSON处理方式
        String contentStr = JsonUtil.toJsonStr(invoke.getData().getContent());
        cn.hutool.json.JSONObject contentJson = JSONUtil.parseObj(contentStr);
        
        String edocId = contentJson.getStr("formRecordId");
        if (StrUtil.isBlank(edocId)) {
            edocId = contentJson.getStr("formRecordCode");
        }
        
        log.info("成功提取edocId: {}", edocId);
        return edocId;
        
    } catch (Exception e) {
        log.error("解析JSON数据失败,原始数据: {}", 
                 invoke.getData().getContent(), e);
        return null;
    }
}

为什么选择Hutool

稳定性更好:Hutool的JSON工具经过了大量实际项目的验证,对各种边界情况处理得更好

API更友好getStr() 方法比 getString() 更安全,不会因为类型问题抛异常

性能不错:虽然不是最快的,但在大多数场景下性能完全够用

维护成本低:API设计简洁,出问题的概率更小

经验总结

避免直接使用 JSON.toJSON():这个方法在处理复杂对象时容易出问题

大数字要小心:超出JavaScript安全整数范围的数字可能会导致解析异常

选择合适的工具:FastJSON虽然性能好,但在某些场景下不如Hutool稳定

异常处理很重要:JSON解析一定要加try-catch,并记录详细的错误信息

测试要充分:要用各种边界数据进行测试,不能只测试正常情况

结语

这次踩坑让我深刻体会到,选择技术工具不能只看性能,稳定性和易用性同样重要。FastJSON在高并发场景下确实性能不错,但对于业务代码来说,稳定性更重要。

到此这篇关于使用FastJSON解析JSON发生异常的踩坑记录的文章就介绍到这了,更多相关FastJSON解析JSON内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决执行maven命令时提示Process terminated的问题

    解决执行maven命令时提示Process terminated的问题

    这篇文章主要介绍了解决执行maven命令时提示Process terminated的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 详解SpringBoot2.0的@Cacheable(Redis)缓存失效时间解决方案

    详解SpringBoot2.0的@Cacheable(Redis)缓存失效时间解决方案

    这篇文章主要介绍了详解SpringBoot2.0的@Cacheable(Redis)缓存失效时间解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Windows部署Jar包的三种方式图文详解

    Windows部署Jar包的三种方式图文详解

    使用Java编写了一些有用的工具,因为不方便部署到服务器上,所以需要把Java生成的jar包在本地Windows上部署,这篇文章主要给大家介绍了关于Windows部署Jar包的三种方式,需要的朋友可以参考下
    2023-07-07
  • 雪花算法(snowflak)生成有序不重复ID的Java实现代码

    雪花算法(snowflak)生成有序不重复ID的Java实现代码

    雪花算法是一种分布式系统中生成唯一ID的方法,由41位时间戳、10位机器码和12位序列号组成,具有唯一性、有序性和高效率等优点,这篇文章主要介绍了雪花算法(snowflak)生成有序不重复ID的Java实现的相关资料,需要的朋友可以参考下
    2024-11-11
  • Spring定时任务只执行一次的原因分析与解决方案

    Spring定时任务只执行一次的原因分析与解决方案

    在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程池问题、异常中断等,本文将深入分析Spring定时任务只执行一次的原因,并提供完整的解决方案,需要的朋友可以参考下
    2025-03-03
  • Java 基础之NIO 学习详解

    Java 基础之NIO 学习详解

    这篇文章主要介绍了java基础之NIO介绍及使用,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-09-09
  • java使用htmlparser提取网页纯文本例子

    java使用htmlparser提取网页纯文本例子

    这篇文章主要介绍了java使用htmlparser提取网页纯文本例子,需要的朋友可以参考下
    2014-04-04
  • SpringBoot 项目使用hutool 工具进行 http 接口调用的处理方法

    SpringBoot 项目使用hutool 工具进行 http 接口调用的处理方

    在实际的开发过程中一个互联网的项目来说 ,有可能会涉及到调用外部接口的实际业务场景,下面通过本文给大家介绍SpringBoot 项目 使用hutool 工具进行 http 接口调用的处理方法,需要的朋友可以参考下
    2022-06-06
  • Java JAR 启动内存参数配置指南(从基础设置到性能优化)

    Java JAR 启动内存参数配置指南(从基础设置到性能优化)

    在启动 Java 可执行 JAR 文件时,合理配置 JVM 内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式指定内存配置,并结合实际场景提供优化建议,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • Java中Collections.sort的使用

    Java中Collections.sort的使用

    本文主要介绍了Java中Collections.sort的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05

最新评论