Here i have used library
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.0'
while comparing JSON by below code
String actualResponse = "{\n" +
" \"employee\":\n" +
" {\n" +
" \"id\": \"1212\",\n" +
" \"fullName\": \"John Miles\",\n" +
" \"age\": 34,\n" +
" \"skills\": [\"Java\", \"C++\", \"Python\"]\n" +
" }\n" +
"}";
String expectedResponse = "{\n" +
" \"employee\":\n" +
" {\n" +
" \"id\": \"1212\",\n" +
" \"age\": 34,\n" +
" \"fullName\": \"John Miles\",\n" +
" \"skills\": [\"Java\", \"C++\"] \n" +
" } \n" +
"}";
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj1 = mapper.readTree(actualResponse);
JsonNode actualObj2 = mapper.readTree(expectedResponse);
assertEquals(actualObj1, actualObj2);
by running above code, the Assertion is failing
Exception in thread "main" java.lang.AssertionError: expected:<{"employee":{"id":"1212","fullName":"John Miles","age":34,"skills":["Java","C++","Python"]}}> but was:<{"employee":{"id":"1212","age":34,"fullName":"John Miles","skills":["Java","C++"]}}>
at org.junit.Assert.fail(Assert.java:89)
at org.junit.Assert.failNotEquals(Assert.java:835)
at org.junit.Assert.assertEquals(Assert.java:120)
at org.junit.Assert.assertEquals(Assert.java:146)
at JsonComparision.EndpointJsonMatcher.verifyJsonInteraction(EndpointJsonMatcher.java:47)
at JsonComparision.EndpointJsonMatcher.main(EndpointJsonMatcher.java:37)
in above example Assertion is failing because length of skills
array is mismatching,
i am searching for a solution so that it can ignore array length while comparing, and it should only compare by data type of value.
import java.util.HashMap;
import static JsonNeastedComp.JsonStructure.GetJsonMap;
public class CompareJsonStruct1 {
public static void main(String[] args) throws Exception {
String actual = "{\n" +
" \"employee\":\n" +
" {\n" +
" \"id\": \"1212\",\n" +
" \"fullName\": \"John Miles\",\n" +
" \"age\": 34,\n" +
" \"skills\": [\"Java\", \"C++\", \"Python\"]\n" +
" }\n" +
"}";
String expected = "{\n" +
" \"employee\":\n" +
" {\n" +
" \"id\": \"1212\",\n" +
" \"age\": 34,\n" +
" \"fullName\": \"John Miles\",\n" +
" \"skills\": [\"Java\", \"C++\"] \n" +
" } \n" +
"}";
HashMap actual_structure = GetJsonMap(actual);
HashMap expected_structure = GetJsonMap(expected);
boolean result = expected_structure.equals(actual_structure);
if (result) {
System.out.println("Matched!");
} else {
System.out.println("Un-matched!");
}
}
}
import org.json.JSONArray;
import org.json.JSONObject;
import org.testcontainers.shaded.com.fasterxml.jackson.core.type.TypeReference;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
import java.util.stream.Collectors;
public class JsonStructure {
static HashMap actual_map;
public static HashMap GetJsonMap(String actual) throws Exception {
actual_map = new HashMap();
ObjectMapper objectMapper = new ObjectMapper();
List<String> all_keys_actual = getKeysInJsonUsingMaps(actual, objectMapper);
all_keys_actual = all_keys_actual.stream().distinct().collect(Collectors.toList());
JSONObject inputJSONOBject = new JSONObject(actual);
for (String key : all_keys_actual) {
getValueOf(inputJSONOBject, key);
}
return actual_map;
}
// In HashMap, Actual Value will be replaced by it's Datatype
public static void parseObject(JSONObject json, String key) {
if(json.get(key) instanceof JSONArray){
actual_map.put(key,"JSONArray");
} else if (json.get(key) instanceof JSONObject) {
actual_map.put(key,"JSONObject");
} else if(json.get(key) instanceof String){
actual_map.put(key,"String");
} else if(json.get(key) instanceof Integer){
actual_map.put(key,"Integer");
}
}
public static List<String> getKeysInJsonUsingMaps(String json, ObjectMapper mapper) throws Exception {
List<String> keys = new ArrayList<>();
Map<String, Object> jsonElements = mapper.readValue(json, new TypeReference<Map<String, Object>>() {
});
getAllKeys(jsonElements, keys);
return keys;
}
// Getting all the keys (including nested keys)
public static void getAllKeys(Map<String, Object> jsonElements, List<String> keys) {
jsonElements.entrySet()
.forEach(entry -> {
keys.add(entry.getKey());
if (entry.getValue() instanceof Map) {
Map<String, Object> map = (Map<String, Object>) entry.getValue();
getAllKeys(map, keys);
} else if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
list.forEach(listEntry -> {
if (listEntry instanceof Map) {
Map<String, Object> map = (Map<String, Object>) listEntry;
getAllKeys(map, keys);
}
});
}
});
}
// Getting value of all the keys (including nested keys value)
public static void getValueOf(JSONObject json, String key) {
boolean exists = json.has(key);
Iterator< ? > keys;
String nextKeys;
if (!exists) {
keys = json.keys();
while (keys.hasNext()) {
nextKeys = (String) keys.next();
try {
if (json.get(nextKeys) instanceof JSONObject) {
if (exists == false) {
getValueOf(json.getJSONObject(nextKeys), key);
}
} else if (json.get(nextKeys) instanceof JSONArray) {
JSONArray jsonarray = json.getJSONArray(nextKeys);
for (int i = 0; i < jsonarray.length(); i++) {
String jsonarrayString = jsonarray.get(i).toString();
JSONObject innerJSOn = new JSONObject(jsonarrayString);
if (exists == false) {
getValueOf(innerJSOn, key);
}
}
}
} catch (Exception e) {
}
}
}
else {
parseObject(json, key);
}
}
}