Java版JsonPath过滤场景下如何实现数据类型转换以支持数值比较
Java 生态 JsonPath 字符串存储数值的过滤适配指南
做接口数据处理时用Java生态的JsonPath开源库已经挺久了,整体体验符合预期,只碰到过一类适配问题:部分第三方接口会把本该是数字类型的统计字段用字符串格式返回,最典型的就是曝光量、消费额这类指标,实际返回值是带引号的字符串。
实际碰到的典型接口返回结构参考:
{ "data":[ { "start_time": "2021-01-26T11:36:10-0800", "insights": { "data": [ { "account_id": "104448579711490", "campaign_id": "6230174444738", "adset_id": "6230236298338", "date_start": "2021-01-12", "date_stop": "2021-02-10", "impressions": "81619", "spend": "33.54" } ], "paging": { "cursors": { "before": "MAZDZD", "after": "MAZDZD" } } }, "id": "6230236298338" } ] }
最初写的过滤表达式目标是筛出存在有效洞察数据、且曝光量大于0的条目,写法如下:
$.data[?(@.insights && @.insights.data && @.insights.data[0].impressions > 0)]
这个表达式在前端的JsonPath在线测试站点能正常跑通匹配,但放到Java项目里的JsonPath库执行就没有返回结果。翻了官方文档也没找到能直接开启“字符串数值自动转数字”的配置项。
排查后发现核心原因:Java版JsonPath的默认过滤逻辑会严格校验比较两侧的类型一致性,字段侧存的是字符串类型的"81619",对比侧写的是数字类型的0,类型不匹配时会直接判定比较结果为假,根本不会做隐式的类型转换。而前端的在线测试站点默认会做宽松的类型转换,所以能正常匹配。
后来经社区用户提示,有一套改动成本极低的适配方案:把对比侧的数值也改成同格式的字符串,就能正常触发匹配逻辑,调整后的可正常运行的表达式如下:
$.data[?(@.insights && @.insights.data && @.insights.data[0].impressions > '0')]
实际验证下来的注意点:
- 这个方案不需要自定义类型转换器、不需要扩展库的内置过滤逻辑,只需要改表达式里的比较值类型就行,改动成本几乎为零
- 这种写法走的是字符串字典序比较,对于全是纯数字的字符串场景,字典序的排序结果和数值排序结果完全一致,不会出现判断偏差
- 如果后续碰到更复杂的比较场景,比如需要处理带小数的消费金额、非等长的大数字字符串,也可以通过库提供的扩展点自定义过滤规则,在比较前先把字符串转成数值类型再判断,不需要改动库的核心源码
内容的提问来源于stack exchange,提问作者Tin Nguyen
相关产品推荐
相关产品推荐

