Получить разницу в двух строках json, игнорируя определенное поле

#java #json #jackson #compare

#java #json #джексон #Сравнить

Вопрос:

Я работаю над сравнением двух строк JSON и получением разницы, если она не одинакова. Здесь я хочу игнорировать несколько полей при сравнении. Предоставит ли Джексон это средство или любая другая библиотека лучше?

Json1:

 {
    "name": "something",
    "id": "1",
    "version": "123"
}
  

Json2:

 {
    "name": "nothing",
    "id": "1",
    "version": "12356"
}
  

Я использую приведенный ниже код, чтобы найти разницу между приведенными выше примерами строк json

 ObjectMapper mapper = new ObjectMapper();
JsonNode node1 = mapper.valueToTree(json1);
JsonNode node2 = mapper.valueToTree(json2);
String diff = JsonDiff.asJson(node1, node2).toString();
logger.info("Difference: "   diff);
  

Но я хочу игнорировать версию при сравнении JSON из приведенного выше примера JSON.

Может ли Jackson сделать это или любую другую доступную библиотеку лучше?

Комментарии:

1. Джексон может сравнивать json со своим методом equal, и для этого требуется пользовательский компаратор: docs

2. @JonathanAndersson, да, но я хочу разницу, игнорируя определенные поля.

3. Как будет выглядеть строка diff? Оно все еще отформатировано как JSON? Если это так, я бы создал объект Java с интересующими вас полями, в данном случае «id» и «name», и десериализовал его в этот класс, а затем, чтобы получить diff в виде строки, я бы еще раз сериализовал его, тогда у вас будет ваш diff в виде строки. Возможно, это не самый быстрый способ, но его легко кодировать.

Ответ №1:

Если вам нужна готовая реализация, вы можете обратиться к:https://github.com/java-json-tools/json-patch

В противном случае, если требуется для простых вложенных объектов, и вы хотите игнорировать свойства во время сравнения, вы можете реализовать ObjectMapper и переопределить метод equals. Чтобы удалить файл из сравнения, вы можете сделать:

 ((ObjectNode)node1).remove("version");
((ObjectNode)node2).remove("version");
  

Затем вы можете просто вызвать свой JsonDiff для анализа.

Комментарии:

1. приведенная выше ссылка ничего не говорит о пропуске определенных полей

Ответ №2:

Я успешно могу достичь этого, используя разные библиотеки :

Импортирует

     import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.flipkart.zjsonpatch.JsonDiff;
    import com.jayway.jsonpath.DocumentContext;
    import com.jayway.jsonpath.JsonPath;
  

Фрагмент кода

 DocumentContext existingDoc = JsonPath.parse(json1);
DocumentContext incomingDoc = JsonPath.parse(json2);

existingDoc.delete("version");
incomingDoc.delete("version");

JsonNode existingNode = mapper.readTree(existingDoc.jsonString());
JsonNode incomingNode = mapper.readTree(incomingDoc.jsonString());

String diffs = JsonDiff.asJson(existingNode, incomingNode).toString();

logger.info("Difference: "   diffs);