Is there any way in java to compare two json objects and print the changes/differences?
I have tried with "Flat-map utility" which is flattening and also comparing the json objects, however diff failed in case of json array elements in different orders in two json objects.
e.g
JSON 1
{
"name":"Jack",
"student_ID":1,
"subject":[
{
"marks":50,
"subjectId":"PHY",
"subjectName":"Physics"
},
{
"marks":60,
"subjectId":"CHE",
"subjectName":"Chemistry"
}
]
}
JSON 2
{
"name":"Jack",
"student_ID":1,
"subject":[
{
"marks":60,
"subjectId":"CHE",
"subjectName":"Chemistry"
},{
"marks":50,
"subjectId":"PHY",
"subjectName":"Physics"
}
]
}
json diff shows the Two jsons are mismatched.. Logically those are identical..
Is there a good way of json matching and comparing in java?
code used:
public class compareUtil
{
public static void main(String[] args) throws IOException, UnresolvedDatasetException, ParseException
{
// TODO Auto-generated method stub
String baselineFolderPath = "input//jsonBaseline";
String regressionfolderPath = "input//jsonRegression";
String fileToCompare = "sampleJson1_simple.json";
String baselineFile = baselineFolderPath + "//" + fileToCompare;
String regressionFile = regressionfolderPath + "//" + fileToCompare;
InputStream getBaselineJsonFile = new FileInputStream(baselineFile);
InputStream getRegressionJsonFile = new FileInputStream(regressionFile);
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> type = new TypeReference<HashMap<String, Object>>() {};
Map<String, Object> baselineMap = mapper.readValue(getBaselineJsonFile, type);
Map<String, Object> regressionMap = mapper.readValue(getRegressionJsonFile, type);
MapDifference<String, Object> differenceNormal = Maps.difference(baselineMap, regressionMap);
System.out.println(differenceNormal);
Map<String, Object> baselineFlatMap = FlatMapUtil.flatten(baselineMap);
Map<String, Object> regressionFlatMap = FlatMapUtil.flatten(regressionMap);
MapDifference<String, Object> difference = Maps.difference(baselineFlatMap, regressionFlatMap);
System.out.println("The diff "+difference);
System.out.println("Entries only on the baseline json\n--------------------------");
difference.entriesOnlyOnLeft()
.forEach((key, value) -> System.out.println(key + ": " + value));
System.out.println("\n\nEntries only on the regression json\n--------------------------");
difference.entriesOnlyOnRight()
.forEach((key, value) -> System.out.println(key + ": " + value));
System.out.println("\n\nEntries differing (baseline, regression)\n--------------------------");
difference.entriesDiffering()
.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
------------------------------------------------------------------------------------------------
public final class FlatMapUtil {
private FlatMapUtil() {
throw new AssertionError("No instances for you!");
}
public static Map<String, Object> flatten(Map<String, Object> map) {
return map.entrySet().stream()
.flatMap(FlatMapUtil::flatten)
.collect(LinkedHashMap::new, (m, e) -> m.put("/" + e.getKey(), e.getValue()), LinkedHashMap::putAll);
}
private static Stream<Map.Entry<String, Object>> flatten(Map.Entry<String, Object> entry) {
if (entry == null) {
return Stream.empty();
}
if (entry.getValue() instanceof Map<?, ?>) {
return ((Map<?, ?>) entry.getValue()).entrySet().stream()
.flatMap(e -> flatten(new AbstractMap.SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue())));
}
if (entry.getValue() instanceof List<?>) {
List<?> list = (List<?>) entry.getValue();
return IntStream.range(0, list.size())
.mapToObj(i -> new AbstractMap.SimpleEntry<String, Object>(entry.getKey() + "/" + i, list.get(i)))
.flatMap(FlatMapUtil::flatten);
}
return Stream.of(entry);
}
}