Jackson Json parser has a nice feature that it can parse a Json String into a Map. You can then query the entries or simply ask on equality:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class Test
{
public static void main(String... args)
{
String input1 = "{\"state\":1,\"cmd\":1}";
String input2 = "{\"cmd\":1,\"state\":1}";
ObjectMapper om = new ObjectMapper();
try {
Map<String, Object> m1 = (Map<String, Object>)(om.readValue(input1, Map.class));
Map<String, Object> m2 = (Map<String, Object>)(om.readValue(input2, Map.class));
System.out.println(m1);
System.out.println(m2);
System.out.println(m1.equals(m2));
} catch (Exception e) {
e.printStackTrace();
}
}
}
The output is
{state=1, cmd=1}
{cmd=1, state=1}
true
Answer from Sharon Ben Asher on Stack OverflowJackson Json parser has a nice feature that it can parse a Json String into a Map. You can then query the entries or simply ask on equality:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class Test
{
public static void main(String... args)
{
String input1 = "{\"state\":1,\"cmd\":1}";
String input2 = "{\"cmd\":1,\"state\":1}";
ObjectMapper om = new ObjectMapper();
try {
Map<String, Object> m1 = (Map<String, Object>)(om.readValue(input1, Map.class));
Map<String, Object> m2 = (Map<String, Object>)(om.readValue(input2, Map.class));
System.out.println(m1);
System.out.println(m2);
System.out.println(m1.equals(m2));
} catch (Exception e) {
e.printStackTrace();
}
}
}
The output is
{state=1, cmd=1}
{cmd=1, state=1}
true
You can also use Gson API
JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{\"state\":1,\"cmd\":1}");
JsonElement o2 = parser.parse("{\"cmd\":1,\"state\":1}");
System.out.println(o1.equals(o2));
I recommend the zjsonpatch library, which presents the diff information in accordance with RFC 6902 (JSON Patch). You can use it with Jackson:
import com.fasterxml.jackson.databind.{ObjectMapper, JsonNode}
JsonNode beforeNode = jacksonObjectMapper.readTree(beforeJsonString);
JsonNode afterNode = jacksonObjectMapper.readTree(afterJsonString);
import com.flipkart.zjsonpatch.JsonDiff
JsonNode patch = JsonDiff.asJson(beforeNode, afterNode);
String diffs = patch.toString();
This library is better than fge-json-patch (which was mentioned in another answer) because it can detect items being inserted/removed from arrays. Fge-json-patch cannot handle that (if an item is inserted into the middle of an array, it will think that item and every item after that was changed since they are all shifted over by one).
I've done good experience with 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);
}
...
Try Skyscreamer's JSONAssert.
Its non-strict mode has two major advantages that make it less brittle:
- Object extensibility (e.g. With an expected value of {id:1}, this would still pass: {id:1,moredata:'x'}.)
- Loose array ordering (e.g. ['dog','cat']==['cat','dog'])
In strict mode it behaves more like json-lib's test class.
A test looks something like this:
@Test
public void testGetFriends() {
JSONObject data = getRESTData("/friends/367.json");
String expected = "{friends:[{id:123,name:\"Corby Page\"}"
+ ",{id:456,name:\"Solomon Duskis\"}]}";
JSONAssert.assertEquals(expected, data, false);
}
The parameters in the JSONAssert.assertEquals() call are expectedJSONString, actualDataString, and isStrict.
The result messages are pretty clear, which is important when comparing really big JSON objects.
As a general architectural point, I usually advise against letting dependencies on a particular serialization format bleed out beyond your storage/networking layer; thus, I'd first recommend that you consider testing equality between your own application objects rather than their JSON manifestations.
Having said that, I'm currently a big fan of Jackson which my quick read of their ObjectNode.equals() implementation suggests does the set membership comparison that you want:
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) {
return false;
}
ObjectNode other = (ObjectNode) o;
if (other.size() != size()) {
return false;
}
if (_children != null) {
for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
String key = en.getKey();
JsonNode value = en.getValue();
JsonNode otherValue = other.get(key);
if (otherValue == null || !otherValue.equals(value)) {
return false;
}
}
}
return true;
}