我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java中json-diff简单使用及对象是否一致源码分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java中json-diff简单使用及对象是否一致源码分析

本篇内容介绍了“java中json-diff简单使用及对象是否一致源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    一、摘要

    今天推荐的是一款java中,对比两个json-diff对象是否一致的工具包 json-diff` 。他可以对比任何结构的两个json数据,并且将其中的不一致信息反馈给用户。工具还内置了很多配置可以来控制对比过程中的行为。目前已经补充大量单测,稳定性还是比较好的。

    二、背景

    公司最近在重构一个核心系统,至于为什么重构原因很多,就不说明了。但是这个核心系统承载较多的线上业务。为了不影响依赖依赖该服务的应用,所以我们重构的最核心就是完全兼容老系统接口。

    为了保证平滑上线,并且测试新系统与老系统是否一致,我们决定系统并行一段时间,并且在这段时间之中验证新接口对老接口的兼容性。我们新起一个代理服务,他会将我们的用户流量分别转发到新老接口,然后拿到两个结果,将老接口结果直接返回;异步去比较新老结果是否符合预期,进行记录或者报警。

    这样系统在经过一段时间的测试,稳定性更高,出错的概率更小。

    java中json-diff简单使用及对象是否一致源码分析

    因为系统都是采用http接口对外提供服务,且返回数据格式统一的是json格式。所以我们急需一款强大的Java语言的Json对比工具来帮助我们发现新老系统的不兼容之处。

    三、工具介绍

    1. 介绍

    json-diff 是一款功能强大的json差异发现工具,支持任何结构的json对比,并且可以将对比结果返给用户。目前该工具更新到了 3.0.0-RC1-RELEASE 版本。最新版可以查看 版本列表 。建议使用最新版,旧版可能存在缺陷。

    优点:

    • 轻量级:工具只依赖 fastjson2

    • 精准定位:可以返回最精准且详细的信息

    • 功能全面:几乎覆盖任何json结构

    • 高性能

    2. 使用教程

    2.1 快速开始
    • 引入依赖

    <dependency>    <groupId>cn.xiaoandcai</groupId>    <artifactId>json-diff</artifactId>    <!-- 旧版本可能存在某些缺陷。版本请以maven仓库最版为准。 -->    <version>${version}</version></dependency>

    版本查看 2022-03-04 最新版本:3.0.0-RC1-RELEASE

    • 开始使用

    public class UseExample {    public static void main(String[] args) {        String array1 = "[1, 2, 3, 4, 5]";        String array2 = "[1, 3, 9, 4, 5]";        JsonComparedOption jsonComparedOption = new JsonComparedOption().setIgnoreOrder(true);        JsonCompareResult jsonCompareResult = new DefaultJsonDifference()                .option(jsonComparedOption)                .detectDiff(JSON.parseArray(array1), JSON.parseArray(array2));        System.out.println(JSON.toJSONString(jsonCompareResult));    }}

    结果展示:

    {    "defectsList": [        {            "actual": 9,            "expect": 2,            "illustrate": "The expect('2') data is inconsistent with the actual('9') data",            "travelPath": {                "abstractTravelPath": "root[]",                "actualTravelPath": "root[2]",                "expectTravelPath": "root[1]"            }        }    ],    "match": false}

    工具会返回 match 表示是否通过比对。defectsList 则是对比信息。

    2.2 更多配置
    配置类型备注
    ignoreOrderboolean是否比较过程中忽略数组顺序
    mappingMap<String, String>将真实字段映射到期望字段,key是真实字段name,value是期望的字段name
    ignorePathSet<String>当对比的路径完全匹配时会被跳过。遇到数组使用 [] 即可。无需填入下标
    ignoreKeySet<String>对比object时。或忽略该key。对整个json生效
    customComparatorMap<String, Class<JsonNeat>>用户自定义比较器。具体说明见下文

    2.0.1-RC1-RELEASE 之后版本中移除了 keyFunction 配置参数。可以使用 ignorePath 来代替达到同样的效果。

    工具提供了四个配置,来之对比过程中一些其他的要求。工具还在积极开发中,如果有新的需求,可以给作者提一个issuse。

    在开发中。很多时候对比配置一致。可以使用 JsonDiffOption 进行开启唯一配置

    3. 进阶

    3.1. 全局使用固定配置

    由于在设计中考虑到各线程比较配置相互独立。所以默认将配置防止在 ThreadLocal 中进行存储。但在大多数情况下,我们在全局比较时,配置并不会发生变化。

    工具提供了全局配置方式。采用的方式是静态类属性。这样也会获得更好的性能。

    // 开启并设置全局配置JsonDiffOption.openUniqueOption();JsonDiffOption.setGloballyUniqueOption(new JsonComparedOption());// 不想使用时可以调用调整回线程独有模式 JsonDiffOption.closeUniqueOption();
    3.2. 数组元素为对象关联

    当我们在遇到数组元素是一个对象时。如下:

    [    {        "date": "23日星期五",        "sunrise": "06:16",        "high": "高温 18.0℃"    },    {        "date": "24日星期六",        "sunrise": "06:14",        "high": "高温 21.0℃"    }]

    在比较时, 如果希望 date 字段一致,则认为两个对象一致。那么可以将 sunrise, high 字段都配置到 ignorePath 中。如:

    HashSet<String> ignorePath = new HashSet<>();ignorePath.add("root[].sunrise");ignorePath.add("root[].high");

    如果只是不想关注某个字段。即是 ignorePath 正常用法。配置如上。

    3.3. 字段映射

    在比较两个对象时。也许由于字段名变更。导致校验不通过。这时可以使用 mapping 配置。将 真实字段名称映射至期望字段名称。在比较过程中会将

    actual.mappingKey 与 expect.mappingValue 认为是应该比较的对象。具体配置如下

    // mapping key 是 actual 键名// mapping value 是 expect 键名HashMap<String, String> mapping = new HashMap<>();mapping.put("date", "sunrise");
    3.4. 字段忽略

    如果有一些字段是想在整个json都进行忽略的,可以使用 ignoreKey 进行全局忽略。当然如果不想全局忽略,但是配置了该项,还是会被忽略掉。

    HashSet&lt;String&gt; ignoreKey = new HashSet&lt;&gt;();ignoreKey.add("sunrise");ignoreKey.add("high");
    3.5 自定义比较器

    在我们一个大json文件下。可能遇到某些节点希望实现自定义比较。可以通过 customComparator 来进行实现。

    它配置的key是一个 travelPath 。具体格式参照 ignorePath 。value 则是一个自定义比较器。对于自定义比较器需要继承对应的抽象类。并且实现具体的抽象接口。具体如下:

    对象比较:

    需要继承 me.codeleep.jsondiff.core.handle.array.AbstractArrayJsonNeat 并且重写以下方法。

    JsonCompareResult detectDiff(JSONObject expect, JSONObject actual);

    数组比较:

    需要继承 me.codeleep.jsondiff.core.handle.object.AbstractObjectJsonNeat 并且重写以下方法。

      JsonCompareResult detectDiff(JSONArray expect, JSONArray actual);// 忽略顺序的比较JsonCompareResult ignoreOrder(JSONArray expect, JSONArray actual);// 保持顺序比较JsonCompareResult keepOrder(JSONArray expect, JSONArray actual);

    基本类型比较:

    基本类型指的是java基础类型的包装类型以及Number的实现类型。

    需要继承 me.codeleep.jsondiff.core.handle.primitive.AbstractPrimitiveJsonNeat 并且重写以下方法。

           JsonCompareResult detectDiff(Object expect, Object actual);

    用户可以自己根据 travelPath 来决定使用何种自定义比较。三种比较器都返回 JsonCompareResult 对象作为当前节点的比较结果。对于JsonCompareResult对象。需要填入以下信息:

    // 示例JsonCompareResult result = new JsonCompareResult();Defects defects = new Defects()                  .setActual(actualDiffJson)                  .setExpect(expectDiffJson)                  .setTravelPath(nextTravelPath)                  .setIllustrateTemplate(DATA_TYPE_INCONSISTENT, expectDiffJson.getClass().getName(), actualDiffJson.getClass().getName());result.addDefects(defects);

    如果遇到在自定义节点中,还需要使用系统自带的比较器时。

    // 该值可以在上述三个抽象类中获得。但需要经自行处理String abstractTravelPath = "root";// 下一级是对象TravelPath nextTravelPath = new TravelPath(abstractTravelPath, mappingKey);// 下一级是数组TravelPath nextTravelPath = new TravelPath(abstractTravelPath, expectIndex, actualIndex);// 获得比较器JsonDiffUtil.getJsonNeat(expectDiffJson, actualDiffJson, nextTravelPath);// 执行比较获得结果JsonCompareResult diff = jsonNeat.diff(expectDiffJson, actualDiffJson, nextTravelPath);// 本级创建的 JsonCompareResult result 将下一级结果合并this.result.mergeDefects(diff.getDefectsList());

    可以使用上述代码获取系统自带的比较器。

    自定义比较器值得注意的是: 从匹配到 travelPath 之后,根据不再接管比较操作。一切行为由用户自行定义。但工具依然预留默认的比较器给用户处理后续字段。这需要用户自行进行组合调用。

    4.其他说明

    前面提到工具几乎可以支持所有json结果的对比校验,并且发现差异。那它到底可以支持哪些呢,不知道是否符合你的需求呢?

    • 对象 ✅

      这是最简单的数据结构了,其中元素都以key-value构成,key是字符串,value可以是任何数据结构。

    • 数组 ✅

      支持严格顺序对比和忽略顺序对比,可以细化数组元素的类型

      • 基本类型 ✅

      • 对象类型 ✅

        该类型在对比时,可以通过ignorePath参数进行元素是否进行比较,将不关心的元素忽略掉。当然ignoreKey也可以,但其是全局生效

      • 数组类型 ✅

        元素也是数组,这样就形成了多维数组,工具理论上来说支持n维数组的对比

      • 元素类型不统一 ✅

        数组中,类型可能包含前面三种类型,这时工具会按照类型分类进行匹配,最后找不到的元素再反馈给用户。

    由于json结构在单个看来,就只有对象和数组两种类型,该工具完美支持了所有类型。

    “java中json-diff简单使用及对象是否一致源码分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    java中json-diff简单使用及对象是否一致源码分析

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    java中json-diff简单使用及对象是否一致源码分析

    本篇内容介绍了“java中json-diff简单使用及对象是否一致源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、摘要今天推荐的是
    2023-07-05

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录