当前位置: 首页 > news >正文

【Bug经验分享】由jsonObject-TypeReference引发的序列化问题

报错

fastjson.JSONException: syntax error, expect {, actual string

背景

InnerResult<Map<Long, Price>> categoryAttributeRequiredSPMResp = JsonUtil.convertJSONString2Object(res, new TypeReference<InnerResult<Map<Long, Price>>>() { });

在这段代码中会出现反序列化 "异常",转换不了Price对象,在之前的测试中一直都是这种方式使用的,也可以转换为Price对象但是,突然在某一天生产上抛出了异常,定位后发现是在这里出现了类型转换异常,复杂对象序列化为json字符串之后,反序列化的时候异常,明明类型是对的,但是就是转换失败,详细代码如下:

public Map<Long, Price> listPriceByIds(List<Long> productIds) {if (CollectionUtils.isEmpty(productIds)) {return new HashMap<>();}String url = spmUrl + "/supplier-product-self-built-product/purchase-price";try {String res = HttpUtils.postBody(url, "json", JSON.toJSONString(productIds));logger.info("获取SPM采购价格,traceId={},请求地址={},请求参数={},响应={}", SwapAreaUtils.getSwapArea().get(Constant.TRACE_KEY), url, JSON.toJSONString(productIds), res);InnerResult<Map<Long, Price>> categoryAttributeRequiredSPMResp = JsonUtil.convertJSONString2Object(res, new TypeReference<InnerResult<Map<Long, Price>>>() {});if (!categoryAttributeRequiredSPMResp.getCode().equals(0)) {return new HashMap<>();}return categoryAttributeRequiredSPMResp.getData();} catch (Exception e) {logger.error("获取SPM采购价格,traceId={},请求地址={},请求参数={}", SwapAreaUtils.getSwapArea().get(Constant.TRACE_KEY), url, JSON.toJSONString(productIds));logger.error("获取SPM采购价格接口失败", e);return new HashMap<>();}
}
/*** 将json串转换为类型为className的对象.* 处理如下json:{'field1':1,'field2':'a'}** @param <T>        类型参数* @param jsonString json字符串* @param type       TypeReference<T>* @return 对象*/
public static <T> T convertJSONString2Object(String jsonString, TypeReference<T> type) {return JSON.parseObject(jsonString, type);
}

修复

public Map<Long, Price> listPriceByIds(List<Long> productIds) {if (CollectionUtils.isEmpty(productIds)) {return new HashMap<>();}String url = spmUrl + "/supplier-product-self-built-product/purchase-price";try {String res = HttpUtils.postBody(url, "json", JSON.toJSONString(productIds));logger.info("获取SPM采购价格,traceId={},请求地址={},请求参数={},响应={}", SwapAreaUtils.getSwapArea().get(Constant.TRACE_KEY), url, JSON.toJSONString(productIds), res);InnerResult<JSONObject> innerResult = JsonUtil.convertJSONString2Object(res, new TypeReference<InnerResult<JSONObject>>() {});if (!innerResult.getCode().equals(0)) {return new HashMap<>();}Map<Long, Price> resultMap = new HashMap<>();for (Map.Entry<String, Object> entry : innerResult.getData().entrySet()) {Price price = JSON.parseObject(JSON.toJSONString(entry.getValue()), Price.class);if (price != null) {resultMap.put(Long.valueOf(entry.getKey()), price);}}return resultMap;} catch (Exception e) {logger.error("获取SPM采购价格,traceId={},请求地址={},请求参数={}", SwapAreaUtils.getSwapArea().get(Constant.TRACE_KEY), url, JSON.toJSONString(productIds));logger.error("获取SPM采购价格接口失败", e);return new HashMap<>();}
}

主要是先将返回值转为 JSONObject 对象,其次取出key,value后自行组装Map这样是稳妥解决了这个类型转换的异常



反思


在定位这个问题的时候,就从来没想过这边会出现问题,因为代码是完全没有动过的,理论上不会有问题,打日志定位后 发现 但是 很鬼畜的事情就是突然发生 类型转换异常,那为什么之前从来没出现过这个问题,怀疑是 alibaba.fastjson 这个包下的TypeReference 序列化 多多少少是有Bug的,不知道是不是版本不稳定引起的--  后面再看看吧

http://www.dtcms.com/a/327005.html

相关文章:

  • 完整多端口 Nginx Docker部署 + GitLab Runner注册及标签使用指南
  • Table Foundation Models: on knowledge pre-training for tabular learning(每日一文)
  • 安卓主题定制实践:17.45MB轻量级主题引擎技术解析
  • Text Animator for Unity快速上手
  • Milvus入门:开源向量数据库,解锁大模型时代的高效检索
  • 面试八股之从jvm层面深入解析Java中的synchronized关键字
  • 【AI绘画】Stable Diffusion webUI 常用功能使用技巧
  • JVM 内存大对象监控和优化实践
  • AT F-Intervals 题解
  • 【KO】大厂常见问题
  • 局域网远程控制/推流
  • 从裸机到云原生:Linux 操作系统实战进阶的“四维跃迁”
  • 嵌入式调试利器:STM32F429移植letter-shell实战
  • 【第四章:大模型(LLM)】05.LLM实战: 实现GPT2-(7)模型训练与微调
  • Apache 服务器基础配置与虚拟主机部署
  • 【自动化备份全网服务器数据项目】
  • 前端,route路由
  • 计算机视觉(7)-纯视觉方案实现端到端轨迹规划(思路梳理)
  • Rsync自动化备份平台建设实战
  • C#对接Ollama,调用大模型禁用思考模式
  • 鸿蒙本地与云端数据双向同步实战:从原理到可运行 Demo 的全流程指南
  • HarmonyOS元服务开发系列教程(三):实现音乐播放和封面旋转
  • 智能家居Agent:物联网设备的统一控制与管理
  • Python函数篇:从零到精通
  • 间隙锁(Gap Lock)
  • 【YOLOV8】小目标困难场景优化
  • 计算机网络---默认网关(Default Gateway)
  • 通用同步/异步收发器USART串口
  • JavaScript的fetch函数的用法
  • C++11新增关键字和范围for循环