Как вы предлагаете эту задачу?
Задача, как я вижу, заключается в том, чтобы разумно представлять информацию об ошибках. Прежде чем я передумаю изобретать колесо, существует ли приемлемый подход к тому, как следует проводить такое сравнение?
Как вы предлагаете эту задачу?
Задача, как я вижу, заключается в том, чтобы разумно представлять информацию об ошибках. Прежде чем я передумаю изобретать колесо, существует ли приемлемый подход к тому, как следует проводить такое сравнение?
Вы можете попробовать архитектуру XStream, обработку сопоставлений JSON
Кроме того, взгляните на это сообщение: Сравнение двух файлов XML и создание третьего с XMLDiff в С#. Это в С#, но логика такая же.
Я рекомендую библиотеку zjsonpatch, которая представляет информацию о различиях в соответствии с RFC 6902 (JSON Patch). Вы можете использовать его с Джексоном:
JsonNode beforeNode = jacksonObjectMapper.readTree(beforeJsonString);
JsonNode afterNode = jacksonObjectMapper.readTree(afterJsonString);
JsonNode patch = JsonDiff.asJson(beforeNode, afterNode);
String diffs = patch.toString();
Эта библиотека лучше, чем fge-json-patch (что упоминалось в другом ответе), поскольку оно может обнаруживать элементы, которые вставляются/удаляются из массивов. Fge-json-patch не может справиться с этим (если элемент вставлен в середину массива, он будет считать, что элемент и каждый элемент после этого были изменены, так как все они сдвинуты на один).
Это касается только равенства, а не различий.
С Джексоном.
ObjectMapper mapper = new ObjectMapper();
JsonNode tree1 = mapper.readTree(jsonInput1);
JsonNode tree2 = mapper.readTree(jsonInput2);
boolean areTheyEqual = tree1.equals(tree2);
Из JavaDoc для JsonNode.equals:
Равенство для объектов узла определяется как полное (глубокое) значение. Это означает, что можно сравнить полные деревья JSON для равенства путем сравнения равенства корневых узлов.
Я отлично поработал с JSONAssert.
import org.junit.Test;
import org.apache.commons.io.FileUtils;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
...
@Test
public void myTest() {
String expectedJson = FileUtils.readFileToString("/expectedFile");
String actualJson = FileUtils.readFileToString("/actualFile");
JSONAssert.assertEquals(expectedJson, actualJson, JSONCompareMode.STRICT);
}
...
У меня была аналогичная проблема, и я написал свою собственную библиотеку:
https://github.com/algesten/jsondiff
Он выполняет как различие/исправление.
Diffs являются самими JSON-объектами и имеют простой синтаксис для слияния/замены объекта и вставки/замены массива.
Пример:
original
{
a: { b: 42 }
}
patch
{
"~a": { c: 43 }
}
Параметр ~
указывает на объединение объекта.
result
{
a: { b: 42, c: 43 }
}
Самый простой способ сравнить строки json - использовать JSONCompare
из библиотеки JSONAssert. Преимущество заключается в том, что он не ограничивается только структурой и может сравнивать значения, если вы хотите:
JSONCompareResult result =
JSONCompare.compareJSON(json1, json2, JSONCompareMode.STRICT);
System.out.println(result.toString());
который выведет что-то вроде:
Expected: VALUE1
got: VALUE2
; field1.field2
Я бы попытался разобрать данные json с помощью json-lib. Это приведет к регулярным Java-объектам, которые можно сравнить с помощью методов equals. Это допустимо только при условии, что ребята из json-lib правильно реализовали метод equals, но вы можете легко протестировать.
Sr. это мое решение для Java-кода, над моим приложением;
try {
// Getting The Array "Courses" from json1 & json2
Courses1 =json1.getJSONArray(TAG_COURSES1);
Courses2 = json2.getJSONArray(TAG_COURSES);
//LOOP FOR JSON1
for(int i = 0; i < Courses1.length(); i++){
//LOOP FOR JSON2
for(int ii = 0; ii < Courses2.length(); ii++){
JSONObject courses1 = Courses1.getJSONObject(i);
JSONObject courses2 = Courses2.getJSONObject(ii);
// Storing each json1 item in variable
int courseID1 = courses1.getInt(TAG_COURSEID1);
Log.e("COURSEID2:", Integer.toString(courseID1));
String Rating1 = courses1.getString(TAG_RATING1);
int Status1 = courses1.getInt(TAG_STATUS1);
Log.e("Status1:", Integer.toString(Status1)); //Put the actual value for Status1 in log.
// Storing each json2 item in variable
int courseID2 = courses2.getInt(TAG_COURSEID);
Log.e("COURSEID2:", Integer.toString(courseID)); //Put the actual value for CourseID in log
String Title2 = courses2.getString(TAG_TITLE);
String instructor2 = courses2.getString(TAG_INSTRUCTOR);
String length2 = courses2.getString(TAG_LENGTH);
String rating2 = courses2.getString(TAG_RATING);
String subject2 = courses2.getString(TAG_SUBJECT);
String description2 = courses2.getString(TAG_DESCRIPTION);
//Status1 = 5 from json1; Incomplete, Status1 =-1 Complete
if(Status1 == 5 && courseID2 == courseID1){
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
//Storing the elements if condition is true.
map.put(TAG_COURSEID, Integer.toString(courseID2)); //pend for compare
map.put(TAG_TITLE, Title2);
map.put(TAG_INSTRUCTOR, instructor2);
map.put(TAG_LENGTH, length2);
map.put(TAG_RATING, rating2);
map.put(TAG_SUBJECT, subject2); //show it
map.put(TAG_DESCRIPTION, description2);
//adding HashList to ArrayList
contactList.add(map);
}//if
}//for2 (json2)
} //for1 (json1)
}//Try
Надеюсь, что это поможет другим, конечно, просто поместите ваши ценности и условия и вид взгляда в этом случае; Hashmap над списком.
Для людей, которые уже используют Джексона, я рекомендую json-patch
final JsonNode patchNode = JsonDiff.asJson(firstNode, secondNode);
System.out.println("Diff=" + m.writeValueAsString(patchNode));