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

FastJson解析对象后验签失败问题分析

背景

项目对接了一个第三方服务,对方返回的结果是json对象response,并且这个response中又嵌套了json对象bizPackage,http请求将返回数据转成了字符串格式,想要解析出来对象内部的签名sign和数据包bizPackage,用于验签,返回数据如下所示:

{"bizPackage":{"resultCode":"00000000","resultDesc":"成功","data":{"mid":"asfadsfadsfadsfads","photo":null},"biz":"fadsgfads","Seq":"596165165","Success":true,"gateway":200},"sign":"465465165165"}

问题

现场反馈服务响应验签失败,通过日志分析,发现如下两个问题:
1、通过FastJson将响应信息格式化之后,参数的顺序发生了变化,可以明显看到返回的响应字符串中参数顺序和格式化后的顺序发生变化
在这里插入图片描述
2、在解决了FastJson格式化顺序错乱的问题之后,又反馈了验签失败,通过日志查看,发现是格式化后将Json对象中value为null的key去除了,如下,当photo为null时,格式化去掉了这个key
在这里插入图片描述

解决方案

对于上面的两个问题,解决方案如下:
1、针对FastJson格式化数据之后,参数顺序发生变化,我们使用的是parseObject方法进行格式化,点进去格式化数据源码,发现parseObject方法是一个重载方法,有如下内容

public static JSONObject parseObject(String str) {if (str != null && !str.isEmpty()) {JSONReader.Context context = createReadContext(JSONFactory.getDefaultObjectReaderProvider(), DEFAULT_PARSER_FEATURE);JSONReader reader = JSONReader.of(str, context);try {Map<String, Object> map = new HashMap();reader.read(map, 0L);JSONObject jsonObject = new JSONObject(map);reader.handleResolveTasks(jsonObject);return jsonObject;} catch (JSONException var5) {Throwable cause = var5.getCause();if (cause == null) {cause = var5;}throw new com.alibaba.fastjson.JSONException(var5.getMessage(), (Throwable)cause);}} else {return null;}}public static JSONObject parseObject(String text, Feature... features) {if (text != null && !text.isEmpty()) {JSONReader.Context context = createReadContext(JSONFactory.getDefaultObjectReaderProvider(), DEFAULT_PARSER_FEATURE, features);JSONReader reader = JSONReader.of(text, context);String defaultDateFormat = DEFFAULT_DATE_FORMAT;if (!"yyyy-MM-dd HH:mm:ss".equals(defaultDateFormat)) {context.setDateFormat(defaultDateFormat);}boolean ordered = false;Feature[] var6 = features;int var7 = features.length;for(int var8 = 0; var8 < var7; ++var8) {Feature feature = var6[var8];if (feature == Feature.OrderedField) {ordered = true;break;}}try {Map<String, Object> map = ordered ? new LinkedHashMap() : new HashMap();reader.read((Map)map, 0L);JSONObject jsonObject = new JSONObject((Map)map);reader.handleResolveTasks(jsonObject);return jsonObject;} catch (JSONException var10) {Throwable cause = var10.getCause();if (cause == null) {cause = var10;}throw new com.alibaba.fastjson.JSONException(var10.getMessage(), (Throwable)cause);}} else {return null;}}

其中,有一段代码是判断是否使用LinkedHashMap的,我们知道这是一个有序的map,对其判断条件是ordered变量,再往上面找发现设置这个变量值的为feature == Feature.OrderedField,因此,我们在格式化参数的时候,加上这个有序属性即可,例如JSONObject.parseObject(s, Feature.OrderedField),这样,我们格式化的对象内部顺序不会改变
2、对于格式化后去掉了值为null的key,这是FastJson的设计,顾名思义FastJson以快为目标,因此,对于值为null的数据,即使保留key,在获取key的时候依然返回null,那就没必要保留这个key了,这样而来获取key返回也是null,不存在歧义,对于这个问题,考虑过直接解析字符串结果,但是由于返回数据格式不固定,风险很大,这里我们选择添加JackSon处理,JackSon格式化数据既能保留顺序也能保留null值key,使用方式如下,添加相关依赖

<!-- Jackson --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.14.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.14.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version></dependency>

下面是测试代码,验证了FastJson和JackSon对于格式化的改变

public static void main(String[] args) throws JsonProcessingException {String s = "{\"bizPackage\":{\"resultCode\":\"00000000\",\"resultDesc\":\"成功\",\"data\":{\"midFile\":\"asfadsfadsfadsfads\",\"photo\":null},\"bizSerial\":\"fadsgfads\",\"bizSeq\":\"596165165\",\"gatewaySuccess\":true,\"gateway\":200},\"sign\":\"465465165165\"}";log.info("请求服务,返回结果:"+s);ObjectMapper mapper = new ObjectMapper();JsonNode responseData = mapper.readTree(s);log.info("请求服务,格式一的:"+responseData);JSONObject jsonObject1 = JSONObject.parseObject(s);log.info("请求服务,格式二的:"+jsonObject1);JSONObject jsonObject = JSONObject.parseObject(s, Feature.OrderedField);log.info("请求服务,格式三的:"+jsonObject);String sign = responseData.get("sign").asText();log.info("请求服务,签名:"+sign);String bizPackage = responseData.get("bizPackage").toString();log.info("请求服务,格式二的:"+bizPackage);}

运行结果为

15:10:49.007 [main] INFO com.example.test.json.test - 请求服务,返回结果:{"bizPackage":{"resultCode":"00000000","resultDesc":"成功","data":{"midFile":"asfadsfadsfadsfads","photo":null},"bizSerial":"fadsgfads","bizSeq":"596165165","gatewaySuccess":true,"gateway":200},"sign":"465465165165"}
15:10:49.500 [main] INFO com.example.test.json.test - 请求服务,格式一的:{"bizPackage":{"resultCode":"00000000","resultDesc":"成功","data":{"midFile":"asfadsfadsfadsfads","photo":null},"bizSerial":"fadsgfads","bizSeq":"596165165","gatewaySuccess":true,"gateway":200},"sign":"465465165165"}
15:10:49.791 [main] INFO com.example.test.json.test - 请求服务,格式二的:{"sign":"465465165165","bizPackage":{"data":{"midFile":"asfadsfadsfadsfads"},"bizSeq":"596165165","gatewaySuccess":true,"resultCode":"00000000","bizSerial":"fadsgfads","resultDesc":"成功","gateway":200}}
15:10:49.792 [main] INFO com.example.test.json.test - 请求服务,格式三的:{"bizPackage":{"resultCode":"00000000","resultDesc":"成功","data":{"midFile":"asfadsfadsfadsfads"},"bizSerial":"fadsgfads","bizSeq":"596165165","gatewaySuccess":true,"gateway":200},"sign":"465465165165"}
15:10:49.796 [main] INFO com.example.test.json.test - 请求服务,签名:465465165165
15:10:49.799 [main] INFO com.example.test.json.test - 请求服务,格式二的:{"resultCode":"00000000","resultDesc":"成功","data":{"midFile":"asfadsfadsfadsfads","photo":null},"bizSerial":"fadsgfads","bizSeq":"596165165","gatewaySuccess":true,"gateway":200}

文章转载自:

http://p2QicFDx.jxtbr.cn
http://vyl5PZSx.jxtbr.cn
http://yWUlukbO.jxtbr.cn
http://WcPYpLhQ.jxtbr.cn
http://0eYLfPsK.jxtbr.cn
http://QaTcENnm.jxtbr.cn
http://I4ih6udG.jxtbr.cn
http://r58PEa2m.jxtbr.cn
http://zUGoVNMg.jxtbr.cn
http://XUklNSgr.jxtbr.cn
http://a1c5MCUe.jxtbr.cn
http://ZzE40C6h.jxtbr.cn
http://WXiT1bUU.jxtbr.cn
http://eIvh86eY.jxtbr.cn
http://SaeVUHp8.jxtbr.cn
http://Zd6YPl4Z.jxtbr.cn
http://JKdiKnzX.jxtbr.cn
http://XAX67hbr.jxtbr.cn
http://zxjAqA6w.jxtbr.cn
http://7niSK7Im.jxtbr.cn
http://IEYOKNFW.jxtbr.cn
http://sTMEKWx2.jxtbr.cn
http://3LTdRI8u.jxtbr.cn
http://nOW1dkjw.jxtbr.cn
http://8Tfaqohk.jxtbr.cn
http://6iQsetfT.jxtbr.cn
http://vDkVOkC8.jxtbr.cn
http://SnQW4rrO.jxtbr.cn
http://nJNDn2rV.jxtbr.cn
http://1Kc5eccD.jxtbr.cn
http://www.dtcms.com/a/380930.html

相关文章:

  • 【Vue2手录12】单文件组件SFC
  • Pinia
  • MySQL按时间Range分区
  • python发送请求SSL验证设置
  • 关于栈和队列的OJ练习
  • WebGIS包括哪些技术栈?怎么学习?
  • 15、优化算法工程实践 - 从数学理论到AI训练的核心引擎
  • VS2019 Community 社区版下载链接
  • 高低压隔离器的技术演进与行业赋能
  • 氚燃料增殖里程碑:MIT新型BABY包层技术实验验证
  • 【案例教程】基于R语言的物种气候生态位动态量化与分布特征模拟实践技术应用
  • 《WINDOWS 环境下32位汇编语言程序设计》第16章 WinSock接口和网络编程(1)
  • 实习总结——关于联调解决的因CRC校验导致协议交互失败的调试经验总结
  • 【从零开始的大模型原理与实践教程】--第三章:预训练语言模型
  • GitHub Copilot支持 GPT-5 和 GPT-5 mini!
  • Day01 Geant4学习
  • 11. 网络同步模型 - 状态同步A
  • Mem0 + Milvus:为人工智能构建持久化长时记忆
  • 力学矢量三角形“无脑”求解指南:基于极角代数的系统化方法
  • 算法第四题移动零(双指针或简便设计),链路聚合(两个交换机配置)以及常用命令
  • 背包问题从入门到入土
  • 远程连接--向日葵
  • 植物灯电源芯片选型指南:如何实现高效与智能?
  • Python读取视频-硬解和软解
  • FFmpeg vs 去水印软件:哪种方式更适合你?
  • Java垃圾回收机制理论算法及使用
  • 【Vue2 ✨】Vue2 入门之旅 · 进阶篇(六):keep-alive 与缓存机制
  • IDA pro 生成idapro.hexlic
  • 【CE】CE教程Tutorial:进阶篇(第8关:多级指针)(Pointer Scan工具)
  • Java 更改 Word 文档中文本颜色