Java:找个好用的 json diff (未完待续)

找个好用的 json diff…

一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package com.tracenote.Utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class BasicDiff {
public static class DiffResult {
private Boolean hasDiff = false;
private String diffMessage;

public Boolean getHasDiff() {
return hasDiff;
}

public void setHasDiff(Boolean hasDiff) {
this.hasDiff = hasDiff;
}

public String getDiffMessage() {
return diffMessage;
}

public void setDiffMessage(String diffMessage) {
this.diffMessage = diffMessage;
}

@Override
public String toString() {
return "DiffResult{" +
"hasDiff=" + hasDiff +
", diffMessage='" + diffMessage + '\'' +
'}';
}
}

DiffResult diffResult = new DiffResult();

public DiffResult compareObject(Object oldObject, Object newObject, String key, int index) {
if (oldObject == null || newObject == null) {
diffResult.hasDiff = true;
diffResult.setDiffMessage(key + " 的value中old和new有一个或者两个为null");
return diffResult;
}
if (oldObject != null && newObject != null) {
if (diffResult.getHasDiff()) {
return diffResult;
}

if (oldObject != null && newObject != null && oldObject.getClass() != newObject.getClass()) {
diffResult.hasDiff = true;
diffResult.setDiffMessage(key + " 的value的old和new 的类型不一致");
return diffResult;
}

if (oldObject instanceof JSONObject && newObject instanceof JSONObject) {
compareJsonObject((JSONObject) oldObject, (JSONObject) newObject, key, index);
if (diffResult.getHasDiff()) {
return diffResult;
}

} else if (oldObject instanceof JSONArray && newObject instanceof JSONArray) {
compareJsonArray((JSONArray) oldObject, (JSONArray) newObject, key, index);
if (diffResult.getHasDiff()) {
return diffResult;
}

} else {
String oldStr = oldObject.toString();
String newStr = newObject.toString();
if (!oldStr.equals(newStr)) {
diffResult.hasDiff = true;
diffResult.setDiffMessage("index: " + index + ", " + key + " 的value中old和new 的值不相等");
return diffResult;
}
}
}
return diffResult;
}

public DiffResult compareJsonArray(JSONArray oldJarr, JSONArray newJarr, String key, int index) {
if (diffResult.getHasDiff()) {
return diffResult;
}
if (oldJarr == null || newJarr == null) {
diffResult.hasDiff = true;
diffResult.setDiffMessage(key + " 的value中两个结果存在null");
return diffResult;
}
if (oldJarr.size() != newJarr.size()) {
diffResult.hasDiff = true;
diffResult.setDiffMessage("index:" + index + ", " + key + " 的value中old和new 数组size不相等");
return diffResult;
}

//jsonarray中元素是个object,排序之后再比较
if (oldJarr.size() > 0 && !(oldJarr.get(0) instanceof JSONObject) && !(oldJarr.get(0) instanceof JSONArray)) {
String[] arrOld = new String[oldJarr.size()];
String[] arrNew = new String[oldJarr.size()];
List<String> tmp = new ArrayList<String>();
for (int i = 0; i < arrOld.length; i++) {
arrOld[i] = oldJarr.get(i).toString();
arrNew[i] = newJarr.get(i).toString();
tmp.add(oldJarr.get(i).toString());
}
Arrays.sort(arrOld);
Arrays.sort(arrNew);
for (int i = 0; i < arrNew.length; i++) {
if (!arrOld[i].equals(arrNew[i])) {
diffResult.hasDiff = true;
diffResult.setDiffMessage("index:" + index + ", " + key + " 的value中第" + tmp.indexOf(arrOld[i]) + "个old和new 值不相等");
return diffResult;
}
}

} else {
for (int i = 0; i < oldJarr.size(); i++) {
if (oldJarr.get(i) != null && newJarr.get(i) != null && oldJarr.get(i).getClass() != newJarr.get(i).getClass()) {
diffResult.hasDiff = true;
diffResult.setDiffMessage("index:" + index + ", " + key + " 的value中old和new 的类型不一致");
return diffResult;
}
if (oldJarr.get(i) instanceof JSONObject) {
JSONObject jold = (JSONObject) oldJarr.get(i);
JSONObject jnew = (JSONObject) newJarr.get(i);
if (jold.equals(jnew)) {
continue;
} else {
Boolean cd = customHasDiff(oldJarr, newJarr, key, i, diffResult);
if (!cd) continue;
compareJsonObject((JSONObject) oldJarr.get(i), (JSONObject) newJarr.get(i), key, i);
if (diffResult.getHasDiff()) {
return diffResult;
}
}
} else if (oldJarr.get(i) instanceof JSONArray) {
compareJsonArray((JSONArray) oldJarr.get(i), (JSONArray) newJarr.get(i), key, i);
if (diffResult.getHasDiff()) {
return diffResult;
}
}
}
}
return diffResult;
}

private Boolean customHasDiff(JSONArray oldJarr, JSONArray newJarr, String key, int i, DiffResult diffResult) {
return true; // TODO
}

public DiffResult compareJsonObject(JSONObject oldJson, JSONObject newJson, String key, int index) {
if (diffResult.getHasDiff()) {
return diffResult;
}
if (oldJson == null || newJson == null) {
diffResult.hasDiff = true;
diffResult.setDiffMessage(key + " 的value中两个结果存在null");
return diffResult;
}

Set<String> sold = oldJson.keySet();
Set<String> snew = newJson.keySet();
if (key.isEmpty()) {
key = "root";
}
//keysize是否相等
if (sold.size() != snew.size()) {
diffResult.hasDiff = true;
diffResult.setDiffMessage(key + " 的keySet的数量不一致,线上有" + sold.size() + "个key,待测服务有" + snew.size() + "个key");
return diffResult;
}

//key是否相同
for (String kold : sold) {
if (!snew.contains(kold)) {
diffResult.hasDiff = true;
diffResult.setDiffMessage("待测服务的" + key + "的keyset不包含" + kold);
return diffResult;
}
}
//value进行校验
for (String kold : sold) {

//此处是进行过滤的,如果哪些字段不需要进行diff,就在这里过滤掉,例如接口返回的globalid,每次返回的值都不一样,不需要进行diff
if (kold.equals("globalId")) {
continue;
}

Object oldObject = oldJson.get(kold);
Object newObject = newJson.get(kold);
compareObject(oldObject, newObject, key + "->" + kold, index);
if (diffResult.getHasDiff()) {
return diffResult;
}

}

return diffResult;
}

public static void main(String[] args) {
String resultOnline = "{\"username\":\"tom\",\"age\":18,\"address\":[{\"province\":\"上海市\"},{\"city\":\"上海市\"},{\"disrtict\":\"静安区\"}]}";
String resultNeedDiff = "{username:\"tom\",age:18}";

JSONObject resultObject1 = JSON.parseObject(resultOnline);
JSONObject resultObject2 = JSON.parseObject(resultNeedDiff);

BasicDiff bf = new BasicDiff();
DiffResult d1 = bf.compareObject(resultObject1, resultObject2, "", 0);

if (d1.getHasDiff()) {

System.out.println("============有diff==========");

System.out.println(d1.getHasDiff());
System.out.println(d1.getDiffMessage());
System.out.println(d1.toString());

}
}
}

###二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.tracenote.Utils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;

import java.util.Iterator;


public class FastJsonDiff {

private static StringBuilder sb = new StringBuilder();


@SuppressWarnings("unchecked")
public static void compareJson(JSONObject json1, JSONObject json2, String key) {
Iterator<String> i = json1.keySet().iterator();
while (i.hasNext()) {
key = i.next();
compareJson(json1.get(key), json2.get(key), key);
}
// return sb.toString();
}

public static void compareJson(Object json1, Object json2, String key) {
if (json1 instanceof JSONObject) {
// System.out.println("this JSONObject----" + key);
compareJson((JSONObject) json1, (JSONObject) json2, key);
} else if (json1 instanceof JSONArray) {
// System.out.println("this JSONArray----" + key);
compareJson((JSONArray) json1, (JSONArray) json2, key);
} else if (json1 instanceof String) {
// System.out.println("this String----" + key);
// compareJson((String) json1, (String) json2, key);
try {
String json1ToStr = json1.toString();
String json2ToStr = json2.toString();
compareJson(json1ToStr, json2ToStr, key);
} catch (Exception e) {
System.out.println("转换发生异常 key:" + key);
e.printStackTrace();
}

} else {
// System.out.println("this other----" + key);
compareJson(json1.toString(), json2.toString(), key);
}
}

public static void compareJson(String str1, String str2, String key) {
if (!str1.equals(str2)) {
sb.append("key:" + key + ",json1:" + str1 + ",json2:" + str2);
System.err.println("不一致key:" + key + ",json1:" + str1 + ",json2:" + str2);
} else {
System.out.println("一致:key:" + key + ",json1:" + str1 + ",json2:" + str2);
}
}

public static void compareJson(JSONArray json1, JSONArray json2, String key) {
if (json1 != null && json2 != null) {
Iterator i1 = json1.iterator();
Iterator i2 = json2.iterator();
while (i1.hasNext()) {
compareJson(i1.next(), i2.next(), key);
}
} else {
if (json1 == null && json2 == null) {
System.err.println("不一致:key:" + key + " 在json1和json2中均不存在");
} else if (json1 == null) {
System.err.println("不一致:key:" + key + " 在json1中不存在");
} else if (json2 == null) {
System.err.println("不一致:key:" + key + " 在json2中不存在");
} else {
System.err.println("不一致:key:" + key + " 未知原因");
}

}
}

private final static String st1 = "{\"username\":\"tom\",\"age\":18,\"address\":[{\"province\":\"上海市\"},{\"city\":\"上海市\"},{\"disrtict\":\"静安区\"}]}";
private final static String st2 = "{username:\"tom\",age:18}";

public static void main(String[] args) {
System.out.println(st1);
JSONObject jsonObject1 = JSONObject.parseObject(st1);
JSONObject jsonObject2 = JSONObject.parseObject(st2);
compareJson(jsonObject1, jsonObject2, null);
}

}

###三:
TODO

https://github.com/fslev/json-compare