最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java對(duì)JSON字符串差異化對(duì)比分析

 更新時(shí)間:2026年03月07日 15:24:39   作者:祁仙森  
文章介紹了兩種對(duì)比Java中JSON字符串差異的方法:使用Jackson包通過自定義過濾規(guī)則和使用json-patch庫,前者可以自定義對(duì)比規(guī)則,而后者具有更好的擴(kuò)展性,文中提供了實(shí)操示例并總結(jié)了經(jīng)驗(yàn)

java JSON字符串差異化對(duì)比

需求是要對(duì)比json,相同可以不展示,不同需指明差異字段

前提引入jackson包

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.13.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.13.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.13.3</version>
    </dependency>
</dependencies>

方式一,使用jsonassert

使用此方法的好處是可以自定義一些對(duì)比規(guī)則(強(qiáng)烈推薦)

  1. 首先引入pom依賴
<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.1</version>
</dependency>
  1. 編寫代碼
public class Main {
    //與jsonStr2中orgSeqNo不一樣,還有addresses中的addrType為103時(shí)的字段類型不一樣
    static String jsonStr1 = "{\"orgSeqNo\":\"123123\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":103,\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    static String jsonStr2 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"103\",\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    //與jsonStr2對(duì)比,addresses數(shù)組中的順序換了
    static String jsonStr3 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"103\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    //與jsonStr2對(duì)比,addresses數(shù)組中的103位數(shù)字類型
    static String jsonStr4 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":103,\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";



    public static void main(String[] args) {
        //aasdasdbc為過濾的節(jié)點(diǎn),隨意指定
        Customization[] customizations = {new Customization("aasdasdbc",(o1, o2) -> { return true;})};
        JSONCompareResult result = null;
        JSONCompareResult result1 = null;
        JSONCompareResult result2 = null;
        try {
            // JSONCompareMode.NON_EXTENSIBLE  不可擴(kuò)展模式,可忽略數(shù)組排序
            // 寬大模式(LENIENT) 可擴(kuò)展,數(shù)組不用排序
            // 嚴(yán)格模式(STRICT)  不可擴(kuò)展, 數(shù)組嚴(yán)格排序
            // 嚴(yán)格排序模式(STRICT_ORDER)  如字面意思,可擴(kuò)展
			// 擴(kuò)展的意思是已有的[1,23,45]和[1,23,45,6]在STRICT_ORDER是可以的

            // 使用自定義比較規(guī)則
            result = JSONCompare.compareJSON(jsonStr1, jsonStr2, new MyCustomComparator(JSONCompareMode.NON_EXTENSIBLE, customizations));
            // 過濾orgSeqNo根節(jié)點(diǎn)字段
            result1  = JSONCompare.compareJSON(jsonStr1, jsonStr3, new CustomComparator(JSONCompareMode.NON_EXTENSIBLE,
                    Customization.customization("orgSeqNo", (o1, o2) -> {
                        return true;
                    })));
            // 過濾orgSeqNo根節(jié)點(diǎn),以及過濾person根節(jié)點(diǎn)下的addresses數(shù)組節(jié)點(diǎn)的addrType節(jié)點(diǎn)字段
            result2 = JSONCompare.compareJSON(jsonStr1, jsonStr3, new CustomComparator(JSONCompareMode.NON_EXTENSIBLE,
                    Customization.customization("orgSeqNo", (o1, o2) -> { return true;}),
                    Customization.customization("person.addresses[*].addrType", (o1, o2) -> { return true;})));
            if (result.passed()) {
                System.out.println("兩者相等");
            } else {
                System.out.println(result.getMessage());
            }
            
            if (result1.passed()) {
                System.out.println("兩者相等");
            } else {
                System.out.println(result1.getMessage());
            }
            if (result2.passed()) {
                System.out.println("兩者相等");
            } else {
                System.out.println(result2.getMessage());
            }
        } catch (JSONException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
  1. 對(duì)比效果
兩者相等
person.addresses[addrId=1].addrType
Expected: 103
     got: 103

兩者相等
  1. 上述自定義的過濾規(guī)則
public class MyCustomComparator extends CustomComparator {
    private final Collection<Customization> customizations;

    public MyCustomComparator(JSONCompareMode mode, Customization[] customizations) {
        super(mode);
        this.customizations = Arrays.asList(customizations);
    }

    //比較器默認(rèn)調(diào)用此方法,如果要實(shí)現(xiàn)復(fù)雜邏輯,可以重寫
    @Override
    public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
        Customization customization = getCustomization(prefix);
        if (customization != null) {
            try {
                if (!customization.matches(prefix, actualValue, expectedValue, result)) {
                    result.fail(prefix, expectedValue, actualValue);
                }
            } catch (ValueMatcherException e) {
                result.fail(prefix, e);
            }
        } else {
			// 過濾某些節(jié)點(diǎn)字段
            if (prefix.indexOf("orgSeqNo") != -1 || prefix.indexOf("addrType") != -1) {
                return;
            }
            // todo 可以設(shè)置一些復(fù)雜的比較,例如某個(gè)字段的數(shù)值字符串和數(shù)值可忽略,小數(shù)和某些整數(shù)可忽略

            if ((expectedValue == null && actualValue != null) || (expectedValue != null && actualValue == null)) {
                result.fail(prefix, expectedValue, actualValue);
            }
            if (expectedValue.getClass().isAssignableFrom(actualValue.getClass())) {
                if (expectedValue instanceof JSONArray) {
                    compareJSONArray(prefix, (JSONArray) expectedValue, (JSONArray) actualValue, result);
                } else if (expectedValue instanceof JSONObject) {
                    compareJSON(prefix, (JSONObject) expectedValue, (JSONObject) actualValue, result);
                } else if (!expectedValue.equals(actualValue)) {
                    result.fail(prefix, expectedValue, actualValue);
                }
            } else {
                result.fail(prefix, expectedValue, actualValue);
            }
        }
    }

    private Customization getCustomization(String path) {
        for (Customization c : customizations) {
            if (c.appliesToPath(path)) {
                return c;
            }
        }
        return null;
    }

}

方式二,使用json-patch

可擴(kuò)展性或者說自定義比較較差

<dependency>
    <groupId>com.github.java-json-tools</groupId>
    <artifactId>json-patch</artifactId>
    <version>1.11</version>
</dependency>
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

實(shí)操舉例

public class Main {
    //與jsonStr2中orgSeqNo不一樣,還有addresses中的addrType為103時(shí)的字段類型不一樣
    static String jsonStr1 = "{\"orgSeqNo\":\"123123\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":103,\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    static String jsonStr2 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"103\",\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    //與jsonStr2對(duì)比,addresses數(shù)組中的順序換了
    static String jsonStr3 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"103\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";
    //與jsonStr2對(duì)比,addresses數(shù)組中的103位數(shù)字類型
    static String jsonStr4 = "{\"orgSeqNo\":\"12e9fc45c09b4a69b7aa2bbcb1313cba\",\"code\":200,\"person\":{\"partyId\":\"10000000001\",\"partyName\":\"張三\",\"partyCertType\":\"10100\",\"partyCertNo\":\"320925199612122314\",\"partyStatus\":\"1\",\"addresses\":[{\"addrId\":\"1\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":103,\"phone\":\"13213137625\"},{\"addrId\":\"2\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"101\",\"phone\":\"13213137625\"},{\"addrId\":\"3\",\"partyId\":\"10000000001\",\"city\":\"蘇州\",\"detailAddr\":\"相城區(qū)雙塔街道33號(hào)\",\"addrType\":\"102\",\"phone\":\"13213137625\"}]},\"message\":\"ok\"}";



    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();
        DocumentContext existingDoc = JsonPath.parse(jsonStr1);
        DocumentContext incomingDoc = JsonPath.parse(jsonStr4);
        existingDoc.delete("orgSeqNo");
        incomingDoc.delete("orgSeqNo");
        JsonNode existingNode = mapper.valueToTree(existingDoc.jsonString());
        JsonNode incomingNode = mapper.valueToTree(incomingDoc.jsonString());
        String diffs = JsonDiff.asJson(existingNode,incomingNode).toString();
        System.out.println("Difference: " + diffs);
    }
}

比較結(jié)果

Difference: []

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Hibernate分頁的兩種實(shí)現(xiàn)方法

    Hibernate分頁的兩種實(shí)現(xiàn)方法

    這篇文章主要介紹了Hibernate分頁的兩種實(shí)現(xiàn)方法,結(jié)合實(shí)例形式講述了criteria分頁與hql分頁的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-03-03
  • springboot構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢的方法

    springboot構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢的方法

    本文主要介紹了springboot怎樣構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Spring事務(wù)annotation原理詳解

    Spring事務(wù)annotation原理詳解

    這篇文章主要介紹了Spring事務(wù)annotation原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring中的@RestControllerAdvice注解使用解析

    Spring中的@RestControllerAdvice注解使用解析

    這篇文章主要介紹了Spring中的@RestControllerAdvice注解使用解析,@RestControllerAdvice?是?Spring?框架中一個(gè)用于統(tǒng)一處理控制器異常和返回結(jié)果的注解,它可以被用來定義全局異常處理程序和全局響應(yīng)結(jié)果處理程序,需要的朋友可以參考下
    2024-01-01
  • Json傳輸出現(xiàn)中文亂碼問題的解決辦法

    Json傳輸出現(xiàn)中文亂碼問題的解決辦法

    最近遇到一個(gè)問題,就是將中文消息以json格式推給微信服務(wù)器時(shí),收到的消息是亂碼,所以下面這篇文章主要給大家介紹了關(guān)于Json傳輸出現(xiàn)中文亂碼問題的解決辦法,需要的朋友可以參考下
    2023-05-05
  • Java日常開發(fā)中讀寫TXT文本舉例詳解

    Java日常開發(fā)中讀寫TXT文本舉例詳解

    這篇文章主要給大家介紹了關(guān)于Java日常開發(fā)中讀寫TXT文本,包括使用BufferedReader、Scanner、FileInputStream等類進(jìn)行讀取,以及使用BufferedWriter、PrintWriter、FileOutputStream等類進(jìn)行寫入,需要的朋友可以參考下
    2024-12-12
  • Java8新特性之泛型的目標(biāo)類型推斷_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java8新特性之泛型的目標(biāo)類型推斷_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    泛型是Java SE 1.5的新特性,泛型的本質(zhì)是參數(shù)化類型,也就是說所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)。下面通過本文給分享Java8新特性之泛型的目標(biāo)類型推斷,感興趣的朋友參考下吧
    2017-06-06
  • Java?static靜態(tài)與非靜態(tài)訪問規(guī)則解析及避坑指南

    Java?static靜態(tài)與非靜態(tài)訪問規(guī)則解析及避坑指南

    Java靜態(tài)和非靜態(tài)成員變量初始化過程解析是Java語言中一個(gè)非常重要的概念,這篇文章主要介紹了Java?static靜態(tài)與非靜態(tài)訪問規(guī)則解析及避坑指南的相關(guān)資料,需要的朋友可以參考下
    2026-05-05
  • java之this關(guān)鍵字用法實(shí)例分析

    java之this關(guān)鍵字用法實(shí)例分析

    這篇文章主要介紹了java之this關(guān)鍵字用法實(shí)例分析,較為詳細(xì)的講述了Java中this關(guān)鍵字的用法及適用范圍,并附帶實(shí)例程序加以說明,需要的朋友可以參考下
    2014-09-09
  • 提示:Decompiled.class file,bytecode version如何解決

    提示:Decompiled.class file,bytecode version如何解決

    在處理Decompiled.classfile和bytecodeversion問題時(shí),通過修改Maven配置文件,添加阿里云鏡像并去掉默認(rèn)鏡像,解決了下載源的問題,同時(shí),檢查并修改了依賴版本,確保了問題的解決
    2024-12-12

最新評(píng)論

新泰市| 延寿县| 南部县| 乌兰察布市| 旬邑县| 麟游县| 夏邑县| 鸡西市| 饶阳县| 三亚市| 曲阜市| 瑞昌市| 阜康市| 肃宁县| 鄂托克旗| 都匀市| 惠安县| 虞城县| 库伦旗| 佛教| 昭平县| 晋州市| 资源县| 富平县| 镇原县| 邵武市| 湘潭市| 阳春市| 韩城市| 军事| 郧西县| 县级市| 香河县| 宁德市| 鲁山县| 江达县| 阜平县| 集贤县| 东明县| 翼城县| 巨鹿县|