亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java中json-diff簡(jiǎn)單使用及對(duì)象是否一致詳解

 更新時(shí)間:2023年03月22日 08:34:29   作者:清炒土豆絲  
這篇文章主要為大家介紹了java中json-diff簡(jiǎn)單使用及對(duì)象是否一致對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、摘要

今天推薦的是一款java中,對(duì)比兩個(gè)json-diff對(duì)象是否一致的工具包 json-diff` 。他可以對(duì)比任何結(jié)構(gòu)的兩個(gè)json數(shù)據(jù),并且將其中的不一致信息反饋給用戶(hù)。工具還內(nèi)置了很多配置可以來(lái)控制對(duì)比過(guò)程中的行為。目前已經(jīng)補(bǔ)充大量單測(cè),穩(wěn)定性還是比較好的。

二、背景

公司最近在重構(gòu)一個(gè)核心系統(tǒng),至于為什么重構(gòu)原因很多,就不說(shuō)明了。但是這個(gè)核心系統(tǒng)承載較多的線上業(yè)務(wù)。為了不影響依賴(lài)依賴(lài)該服務(wù)的應(yīng)用,所以我們重構(gòu)的最核心就是完全兼容老系統(tǒng)接口。

為了保證平滑上線,并且測(cè)試新系統(tǒng)與老系統(tǒng)是否一致,我們決定系統(tǒng)并行一段時(shí)間,并且在這段時(shí)間之中驗(yàn)證新接口對(duì)老接口的兼容性。我們新起一個(gè)代理服務(wù),他會(huì)將我們的用戶(hù)流量分別轉(zhuǎn)發(fā)到新老接口,然后拿到兩個(gè)結(jié)果,將老接口結(jié)果直接返回;異步去比較新老結(jié)果是否符合預(yù)期,進(jìn)行記錄或者報(bào)警。

這樣系統(tǒng)在經(jīng)過(guò)一段時(shí)間的測(cè)試,穩(wěn)定性更高,出錯(cuò)的概率更小。

因?yàn)橄到y(tǒng)都是采用http接口對(duì)外提供服務(wù),且返回?cái)?shù)據(jù)格式統(tǒng)一的是json格式。所以我們急需一款強(qiáng)大的Java語(yǔ)言的Json對(duì)比工具來(lái)幫助我們發(fā)現(xiàn)新老系統(tǒng)的不兼容之處。

三、工具介紹

1. 介紹

json-diff 是一款功能強(qiáng)大的json差異發(fā)現(xiàn)工具,支持任何結(jié)構(gòu)的json對(duì)比,并且可以將對(duì)比結(jié)果返給用戶(hù)。目前該工具更新到了 3.0.0-RC1-RELEASE 版本。最新版可以查看 版本列表 。建議使用最新版,舊版可能存在缺陷。

優(yōu)點(diǎn):

  • 輕量級(jí):工具只依賴(lài) fastjson2
  • 精準(zhǔn)定位:可以返回最精準(zhǔn)且詳細(xì)的信息
  • 功能全面:幾乎覆蓋任何json結(jié)構(gòu)
  • 高性能

2. 使用教程

2.1 快速開(kāi)始

  • 引入依賴(lài)
<dependency>
    <groupId>cn.xiaoandcai</groupId>
    <artifactId>json-diff</artifactId>
    <!-- 舊版本可能存在某些缺陷。版本請(qǐng)以maven倉(cāng)庫(kù)最版為準(zhǔn)。 -->
    <version>${version}</version>
</dependency>

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

  • 開(kāi)始使用
/**
 * @author: codeleep
 * @createTime: 2022/11/22 16:57
 * @description: 使用示例
 */
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));
    }
}

結(jié)果展示:

{
    "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
}

工具會(huì)返回 match 表示是否通過(guò)比對(duì)。defectsList 則是對(duì)比信息。

2.2 更多配置

配置類(lèi)型備注
ignoreOrderboolean是否比較過(guò)程中忽略數(shù)組順序
mappingMap<String, String>將真實(shí)字段映射到期望字段,key是真實(shí)字段name,value是期望的字段name
ignorePathSet<String>當(dāng)對(duì)比的路徑完全匹配時(shí)會(huì)被跳過(guò)。遇到數(shù)組使用 [] 即可。無(wú)需填入下標(biāo)
ignoreKeySet<String>對(duì)比object時(shí)?;蚝雎栽搆ey。對(duì)整個(gè)json生效
customComparatorMap<String, Class<JsonNeat>>用戶(hù)自定義比較器。具體說(shuō)明見(jiàn)下文

2.0.1-RC1-RELEASE 之后版本中移除了 keyFunction 配置參數(shù)。可以使用 ignorePath 來(lái)代替達(dá)到同樣的效果。

工具提供了四個(gè)配置,來(lái)之對(duì)比過(guò)程中一些其他的要求。工具還在積極開(kāi)發(fā)中,如果有新的需求,可以給作者提一個(gè)issuse。

在開(kāi)發(fā)中。很多時(shí)候?qū)Ρ扰渲靡恢???梢允褂?JsonDiffOption 進(jìn)行開(kāi)啟唯一配置

3. 進(jìn)階

3.1. 全局使用固定配置

由于在設(shè)計(jì)中考慮到各線程比較配置相互獨(dú)立。所以默認(rèn)將配置防止在 ThreadLocal 中進(jìn)行存儲(chǔ)。但在大多數(shù)情況下,我們?cè)谌直容^時(shí),配置并不會(huì)發(fā)生變化。

工具提供了全局配置方式。采用的方式是靜態(tài)類(lèi)屬性。這樣也會(huì)獲得更好的性能。

// 開(kāi)啟并設(shè)置全局配置
JsonDiffOption.openUniqueOption();
JsonDiffOption.setGloballyUniqueOption(new JsonComparedOption());
// 不想使用時(shí)可以調(diào)用調(diào)整回線程獨(dú)有模式
 JsonDiffOption.closeUniqueOption();

3.2. 數(shù)組元素為對(duì)象關(guān)聯(lián)

當(dāng)我們?cè)谟龅綌?shù)組元素是一個(gè)對(duì)象時(shí)。如下:

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

在比較時(shí), 如果希望 date 字段一致,則認(rèn)為兩個(gè)對(duì)象一致。那么可以將 sunrise, high 字段都配置到 ignorePath 中。如:

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

如果只是不想關(guān)注某個(gè)字段。即是 ignorePath 正常用法。配置如上。

3.3. 字段映射

在比較兩個(gè)對(duì)象時(shí)。也許由于字段名變更。導(dǎo)致校驗(yàn)不通過(guò)。這時(shí)可以使用 mapping 配置。將 真實(shí)字段名稱(chēng)映射至期望字段名稱(chēng)。在比較過(guò)程中會(huì)將

actual.mappingKey 與 expect.mappingValue 認(rèn)為是應(yīng)該比較的對(duì)象。具體配置如下

// mapping key 是 actual 鍵名
// mapping value 是 expect 鍵名
HashMap<String, String> mapping = new HashMap<>();
mapping.put("date", "sunrise");

3.4. 字段忽略

如果有一些字段是想在整個(gè)json都進(jìn)行忽略的,可以使用 ignoreKey 進(jìn)行全局忽略。當(dāng)然如果不想全局忽略,但是配置了該項(xiàng),還是會(huì)被忽略掉。

HashSet&lt;String&gt; ignoreKey = new HashSet&lt;&gt;();
ignoreKey.add("sunrise");
ignoreKey.add("high");

3.5 自定義比較器

在我們一個(gè)大json文件下??赡苡龅侥承┕?jié)點(diǎn)希望實(shí)現(xiàn)自定義比較??梢酝ㄟ^(guò) customComparator 來(lái)進(jìn)行實(shí)現(xiàn)。

它配置的key是一個(gè) travelPath 。具體格式參照 ignorePath 。value 則是一個(gè)自定義比較器。對(duì)于自定義比較器需要繼承對(duì)應(yīng)的抽象類(lèi)。并且實(shí)現(xiàn)具體的抽象接口。具體如下:

對(duì)象比較:

需要繼承 me.codeleep.jsondiff.core.handle.array.AbstractArrayJsonNeat 并且重寫(xiě)以下方法。

/**
* 比較對(duì)象
* @param expect 期望的json對(duì)象
* @param actual 實(shí)際的json對(duì)象
* @return 返回比較結(jié)果
* @throws IllegalAccessException 發(fā)生異常直接拋出
*/
JsonCompareResult detectDiff(JSONObject expect, JSONObject actual);

數(shù)組比較:

需要繼承 me.codeleep.jsondiff.core.handle.object.AbstractObjectJsonNeat 并且重寫(xiě)以下方法。

  /**
 * 比較數(shù)組.調(diào)用入口。需要自己去分別調(diào)用 ignoreOrder 和  keepOrder。
 * @param expect 期望的json對(duì)象
 * @param actual 實(shí)際的json對(duì)象
 * @return 返回比較結(jié)果
 */
JsonCompareResult detectDiff(JSONArray expect, JSONArray actual);
// 忽略順序的比較
JsonCompareResult ignoreOrder(JSONArray expect, JSONArray actual);
// 保持順序比較
JsonCompareResult keepOrder(JSONArray expect, JSONArray actual);

基本類(lèi)型比較:

基本類(lèi)型指的是java基礎(chǔ)類(lèi)型的包裝類(lèi)型以及Number的實(shí)現(xiàn)類(lèi)型。

需要繼承 me.codeleep.jsondiff.core.handle.primitive.AbstractPrimitiveJsonNeat 并且重寫(xiě)以下方法。

   /**
     * 比較數(shù)組
     * @param expect 基礎(chǔ)類(lèi)型對(duì)象
     * @param actual 基礎(chǔ)類(lèi)型對(duì)象
     * @return 返回比較結(jié)果
     */
    JsonCompareResult detectDiff(Object expect, Object actual);

用戶(hù)可以自己根據(jù) travelPath 來(lái)決定使用何種自定義比較。三種比較器都返回 JsonCompareResult 對(duì)象作為當(dāng)前節(jié)點(diǎn)的比較結(jié)果。對(duì)于JsonCompareResult對(duì)象。需要填入以下信息:

// 示例
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);

如果遇到在自定義節(jié)點(diǎn)中,還需要使用系統(tǒng)自帶的比較器時(shí)。

// 該值可以在上述三個(gè)抽象類(lèi)中獲得。但需要經(jīng)自行處理
String abstractTravelPath = "root";
// 下一級(jí)是對(duì)象
TravelPath nextTravelPath = new TravelPath(abstractTravelPath, mappingKey);
// 下一級(jí)是數(shù)組
TravelPath nextTravelPath = new TravelPath(abstractTravelPath, expectIndex, actualIndex);
// 獲得比較器
JsonDiffUtil.getJsonNeat(expectDiffJson, actualDiffJson, nextTravelPath);
// 執(zhí)行比較獲得結(jié)果
JsonCompareResult diff = jsonNeat.diff(expectDiffJson, actualDiffJson, nextTravelPath);
// 本級(jí)創(chuàng)建的 JsonCompareResult result 將下一級(jí)結(jié)果合并
this.result.mergeDefects(diff.getDefectsList());

可以使用上述代碼獲取系統(tǒng)自帶的比較器。

自定義比較器值得注意的是: 從匹配到 travelPath 之后,根據(jù)不再接管比較操作。一切行為由用戶(hù)自行定義。但工具依然預(yù)留默認(rèn)的比較器給用戶(hù)處理后續(xù)字段。這需要用戶(hù)自行進(jìn)行組合調(diào)用。

4.其他說(shuō)明

前面提到工具幾乎可以支持所有json結(jié)果的對(duì)比校驗(yàn),并且發(fā)現(xiàn)差異。那它到底可以支持哪些呢,不知道是否符合你的需求呢?

  • 對(duì)象 ?

    這是最簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)了,其中元素都以key-value構(gòu)成,key是字符串,value可以是任何數(shù)據(jù)結(jié)構(gòu)。

  • 數(shù)組 ?

    支持嚴(yán)格順序?qū)Ρ群秃雎皂樞驅(qū)Ρ?,可以?xì)化數(shù)組元素的類(lèi)型

    • 基本類(lèi)型 ?

    • 對(duì)象類(lèi)型 ?

      該類(lèi)型在對(duì)比時(shí),可以通過(guò)ignorePath參數(shù)進(jìn)行元素是否進(jìn)行比較,將不關(guān)心的元素忽略掉。當(dāng)然ignoreKey也可以,但其是全局生效

    • 數(shù)組類(lèi)型 ?

      元素也是數(shù)組,這樣就形成了多維數(shù)組,工具理論上來(lái)說(shuō)支持n維數(shù)組的對(duì)比

    • 元素類(lèi)型不統(tǒng)一 ?

      數(shù)組中,類(lèi)型可能包含前面三種類(lèi)型,這時(shí)工具會(huì)按照類(lèi)型分類(lèi)進(jìn)行匹配,最后找不到的元素再反饋給用戶(hù)。

由于json結(jié)構(gòu)在單個(gè)看來(lái),就只有對(duì)象和數(shù)組兩種類(lèi)型,該工具完美支持了所有類(lèi)型。

測(cè)試用例

目前工具測(cè)試覆蓋率已經(jīng)達(dá)到80%。剩余測(cè)試用例正在補(bǔ)全中,完全可用于生產(chǎn)環(huán)境。

以上就是json-diff簡(jiǎn)單使用的詳細(xì)內(nèi)容,更多關(guān)于json-diff簡(jiǎn)單使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Hadoop MultipleOutputs輸出到多個(gè)文件中的實(shí)現(xiàn)方法

    Hadoop MultipleOutputs輸出到多個(gè)文件中的實(shí)現(xiàn)方法

    這篇文章主要介紹了 Hadoop MultipleOutputs輸出到多個(gè)文件中的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • 使用jib插件為Java應(yīng)用構(gòu)建鏡像的方法

    使用jib插件為Java應(yīng)用構(gòu)建鏡像的方法

    這篇文章主要介紹了使用jib插件為Java應(yīng)用構(gòu)建鏡像,要是用戶(hù)本地沒(méi)安裝docker,可以使用jib制作出帶有鏡像的tar文件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • 基于Lombok集成springboot遇到的坑

    基于Lombok集成springboot遇到的坑

    這篇文章主要介紹了Lombok集成springboot遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java反射概念與使用實(shí)例代碼

    Java反射概念與使用實(shí)例代碼

    JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法,下面這篇文章主要給大家介紹了關(guān)于Java反射概念與使用的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • java簡(jiǎn)單實(shí)現(xiàn)數(shù)組的增刪改查方法

    java簡(jiǎn)單實(shí)現(xiàn)數(shù)組的增刪改查方法

    這篇文章主要介紹了Java數(shù)組的增刪改查的示例,幫助大家更好的利用Java處理數(shù)據(jù),感興趣的朋友可以了解下,希望能給你帶來(lái)幫助
    2021-07-07
  • Windows下Java+MyBatis框架+MySQL的開(kāi)發(fā)環(huán)境搭建教程

    Windows下Java+MyBatis框架+MySQL的開(kāi)發(fā)環(huán)境搭建教程

    這篇文章主要介紹了Windows下Java+MyBatis框架+MySQL的開(kāi)發(fā)環(huán)境搭建教程,Mybatis對(duì)普通SQL語(yǔ)句的支持非常好,需要的朋友可以參考下
    2016-04-04
  • Java Socket+mysql實(shí)現(xiàn)簡(jiǎn)易文件上傳器的代碼

    Java Socket+mysql實(shí)現(xiàn)簡(jiǎn)易文件上傳器的代碼

    最近在做一個(gè)小項(xiàng)目,項(xiàng)目主要需求是實(shí)現(xiàn)一個(gè)文件上傳器,通過(guò)客戶(hù)端的登陸,把本地文件上傳到服務(wù)器的數(shù)據(jù)庫(kù)(本地的)。下面通過(guò)本文給大家分享下實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧
    2016-10-10
  • JdbcTemplate方法介紹與增刪改查操作實(shí)現(xiàn)

    JdbcTemplate方法介紹與增刪改查操作實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于JdbcTemplate方法與增刪改查操作實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用JdbcTemplate具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享

    java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享

    這篇文章主要介紹了java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享,本文中使用的是QQ在線接口,也可以使用新浪、淘寶等提供的在線接口,需要的朋友可以參考下
    2014-08-08
  • Java ThreadLocal的使用詳解

    Java ThreadLocal的使用詳解

    ThreadLocal是線程私有的局部變量存儲(chǔ)容器,可以理解成每個(gè)線程都有自己專(zhuān)屬的存儲(chǔ)容器,用來(lái)存儲(chǔ)線程私有變量。ThreadLocal 在日常開(kāi)發(fā)框架中應(yīng)用廣泛,但用不好也會(huì)出現(xiàn)各種問(wèn)題,本文就此講解一下。
    2021-05-05

最新評(píng)論