Ad

Find Json Diff And Then Save In New File, Then On Get Call Return Json Merge Of NewFile With Original File, Java

- 1 answer

I have two complex jsons, one default and other with changes in default, say modifiedDefault. Json will have nested Jsons as well as arrays.

I am using jsonPatch to find diff and it returns a list of diffs. Now I want to save these changes as Json, back in modifiedDefault file.

Now on a get call, I want to merge the modifiedDefault and default files by overriding the values of default by modifiedDefault then return the Json.

Initially I decided to store the path and values returned from JsonPatch in new file but its not working when I try to merge that with default.

Its a java string boot project and I am stuck after finding diffs. As I am not able to apply and save changes as Json back in modifiedDefault file. And that affects merge part of the problem too.

It is very easy to implement this in javascript using json-diff and json-merge libraries but in java, I would really appreciate some inputs. Or some resources. Because most of the resources on jsonPatch are not vert intuitive for a beginner.

input:


{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

modified input



{
    "glossary": {
        "title": "example glossary",
        "location": "dc",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "Acronym": "SGML2",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML"],
                        "another": ["sj", "pj"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

Diff

{
    "glossary": {
        "location": "dc",
        "GlossDiv": {
            "GlossList": {
                "GlossEntry": {
                    "Acronym": "SGML2",
                    "GlossDef": {
                        "GlossSeeAlso": ["GML"],
                        "another": ["sj", "pj"]
                    }
                }
            }
        }
    }
}

after merge

{
    "glossary": {
        "title": "example glossary",
        "location": "dc",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML2",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"],
                        "another": ["sj", "pj"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

I need to save diff in modifiedDefault file and If user wants to make changes again then I will give him the data after merging default with diff.

Ad

Answer

Merging the two objects and writing the result back to a file can be done very easily using ObjectMapper's readerForUpdating method, e.g.

public static void merge() throws IOException {
        final var objectMapper = new ObjectMapper();
        final var obj1 = objectMapper.readValue(
                new FileInputStream(<path-to-input-file.json>),
                new TypeReference<Map<String, Object>>() {
                });

        final var updater = objectMapper.readerForUpdating(obj1);
        
        final var merged = updater.readValue(new FileInputStream(<path-to-modified-file.json));

        objectMapper.writeValue(new File("merge-result.json"), merged);
    }

The only problem is that arrays get actually merged and are not considered as a Set as in your example. So the output after merge will be:

{
    "glossary": {
        "title": "example glossary",
        "location": "dc",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML2",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML", "GML"],
                        "another": ["sj", "pj"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

If that's a problem, you could iterate the object-tree of the merged object, check for arrays and remove duplicates before writing it to the result-file.

Ad
source: stackoverflow.com
Ad