使用JsonAssert比对JSON时如何忽略对象键仅校验内部子字段
需求实现方案
你需要的忽略JSON中values节点下动态键、仅比对子对象内容的需求完全可以通过常见的JSON比对库实现,以下是两种可直接落地的实现方式:
方式1:基于JsonAssert实现
推荐优先用提取values子对象转数组比对的方案,逻辑简单无额外学习成本:
import org.json.JSONArray; import org.json.JSONObject; import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; import java.util.stream.Collectors; public class JsonCompareTest { public void compareJson() throws Exception { // 待比对的两个JSON字符串 String sourceJson = "第一个JSON串内容"; String targetJson = "第二个JSON串内容"; // 提取两个JSON的values下所有子对象,忽略外层动态键 JSONObject sourceValues = new JSONObject(sourceJson).getJSONObject("values"); JSONObject targetValues = new JSONObject(targetJson).getJSONObject("values"); // 子对象转为JSON数组,开启无序比对模式匹配内容 JSONArray sourceArr = new JSONArray(sourceValues.keySet().stream().map(sourceValues::get).collect(Collectors.toList())); JSONArray targetArr = new JSONArray(targetValues.keySet().stream().map(targetValues::get).collect(Collectors.toList())); // 执行比对,LENIENT模式下自动忽略字段顺序、额外字段 JSONAssert.assertEquals(sourceArr, targetArr, JSONCompareMode.LENIENT); } }
如果不想手动提取节点,也可以自定义JsonAssert比较器,匹配values.*路径时跳过键名校验,直接比较子对象内容。
方式2:基于JsonUnit实现
JsonUnit内置通配符路径匹配能力,代码更简洁:
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; public class JsonCompareTest { public void compareJson() { String sourceJson = "第一个JSON串内容"; String targetJson = "第二个JSON串内容"; assertThatJson(targetJson) .when(IGNORING_ARRAY_ORDER) // 忽略values下所有动态键的名称校验,仅匹配子对象内容 .whenIgnoringPaths("values.*") .isEqualTo(sourceJson); } }
内容的提问来源于stack exchange,提问作者Chamupathi Gigara Hettige
相关产品推荐
相关产品推荐

