狂野飙车6鸿蒙版
471.84M · 2025-10-31
最近在开发电子签名项目时遇到了一个特别头疼的问题,系统在处理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.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);
既然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;
}
}
getStr() 方法比 getString() 更安全,不会因为类型问题抛异常这次踩坑让我深刻体会到,选择技术工具不能只看性能,稳定性和易用性同样重要。FastJSON在高并发场景下确实性能不错,但对于业务代码来说,稳定性更重要。
希望这篇文章能帮助到遇到类似问题的朋友。如果你也遇到过类似的JSON解析问题,欢迎在评论区分享你的解决方案!
本文档基于实际项目开发中遇到的问题总结而成,如有疑问欢迎交流讨论。
本文首发于[掘金/CSDN],作者:[听雨],转载请注明出处。