How do I get differences between two json objects using GSON? - java

I used this code to compare two JSON object using Gson in Android:
String json1 = "{\"name\": \"ABC\", \"city\": \"XYZ\"}";
String json2 = "{\"city\": \"XYZ\", \"name\": \"ABC\"}";
JsonParser parser = new JsonParser();
JsonElement t1 = parser.parse(json1);
JsonElement t2 = parser.parse(json2);
boolean match = t2.equals(t1);
Is there any way two get the differences between two objects using Gson in a JSON format?

If you deserialize the objects as a Map<String, Object>, you can with Guava also, you can use Maps.difference to compare the two resulting maps.
Note that if you care about the order of the elements, Json doesn't preserve order on the fields of Objects, so this method won't show those comparisons.
Here's the way you do it:
public static void main(String[] args) {
String json1 = "{\"name\":\"ABC\", \"city\":\"XYZ\", \"state\":\"CA\"}";
String json2 = "{\"city\":\"XYZ\", \"street\":\"123 anyplace\", \"name\":\"ABC\"}";
Gson g = new Gson();
Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> firstMap = g.fromJson(json1, mapType);
Map<String, Object> secondMap = g.fromJson(json2, mapType);
System.out.println(Maps.difference(firstMap, secondMap));
}
This program outputs:
not equal: only on left={state=CA}: only on right={street=123 anyplace}
Read more here about what information the resulting MapDifference object contains.

Related

How to convert jsonarray into map or something else format which can be compared with datastax value

I have JSON Array which I want to convert in some format which I can compare with datastax value.
I tried below code:
String familyNames = response.jsonPath().getString("FAMILY");
and
List jsonresponse = response.jsonPath().getList("$");
I am not able to find any way.
I expect a format in which I can comapre entire json response with the values in datastax table
Consider blogs such as this one or this one or posts like this one or this one here:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
....
String json = "[{\"name\":\"mkyong\", \"age\":37}, {\"name\":\"fong\", \"age\":38}]";
ObjectMapper mapper = new ObjectMapper();
List<Person> persons = Arrays.asList(mapper.readValue(json, Person[].class));
Or
String jsonString = "{'Bob' : {'name': 'Bob Willis'},"
+ "'Jenny' : {'name': 'Jenny McCarthy'}, "
+ "'Steve' : {'name': 'Steven Waugh'}}";
Gson gson = new Gson();
Type empMapType = new TypeToken<Map<String, Employee>>() {}.getType();
Map<String, Employee> nameEmployeeMap = gson.fromJson(jsonString, empMapType);

Get JSON key name using GSON

I have a JSON array which contains objects such as this:
{
"bjones": {
"fname": "Betty",
"lname": "Jones",
"password": "ababab",
"level": "manager"
}
}
my User class has a username which would require the JSON object's key to be used. How would I get the key of my JSON object?
What I have now is getting everything and creating a new User object, but leaving the username null. Which is understandable because my JSON object does not contain a key/value pair for "username":"value".
Gson gson = new Gson();
JsonParser p = new JsonParser();
JsonReader file = new JsonReader(new FileReader(this.filename));
JsonObject result = p.parse(file).getAsJsonObject().getAsJsonObject("bjones");
User newUser = gson.fromJson(result, User.class);
// newUser.username = null
// newUser.fname = "Betty"
// newUser.lname = "Jones"
// newUser.password = "ababab"
// newUser.level = "manager"
edit:
I'm trying to insert "bjones" into newUser.username with Gson, sorry for the lack of clarification
Use entrySet to get the keys. Loop through the entries and create a User for every key.
JsonObject result = p.parse(file).getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entrySet = result.entrySet();
for(Map.Entry<String, JsonElement> entry : entrySet) {
User newUser = gson.fromJson(p.getAsJsonObject(entry.getKey()), User.class);
newUser.username = entry.getKey();
//code...
}
Using keySet() directly excludes the necessity in iteration:
ArrayList<String> objectKeys =
new ArrayList<String>(
myJsonObject.keySet());
Your JSON is fairly simple, so even the manual sort of methods (like creating maps of strings etc for type) will work fine.
For complex JSONs(where there are many nested complex objects and lists of other complex objects inside your JSON), you can create POJO for your JSON with some tool like http://www.jsonschema2pojo.org/
And then just :
final Gson gson = new Gson();
final MyJsonModel obj = gson.fromJson(response, MyJsonModel.class);
// Just access your stuff in object. Example
System.out.println(obj.getResponse().getResults().get(0).getId());

String value as Object key

Let's say I've got String A = "A"; and String B = "B"; and I want to use these values as keys in a json object.
{
"A":"string1",
"B":"string2"
}
Now in another time and space, I'd like to get these String values from the Json Object. I'd have to get the value for "A" and "B". We can just use A and B when making this json object and reuse them when getting the values.
However, I'm trying to make a Json Object from an actual Object. I'm using Gson to achieve this. How can I use A and B as keys when making the object?
Using Gson you can parse the JSON into a Map as
String json = "{\n" +
"\"A\":\"string1\",\n" +
"\"B\":\"string2\"\n" +
"}";
Gson gson = new Gson();
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> map = gson.fromJson(json, type);
System.out.println(map.get("A")); // string1
System.out.println(map.get("B")); // string2
Alternatively, if you want to wrap the keys in an already existing object
String json = "{ pairs : {\n" +
"\"A\":\"string1\",\n" +
"\"B\":\"string2\"\n" +
"} }";
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
System.out.println(jsonObject.getPairs().get("A")); // string1
System.out.println(jsonObject.getPairs().get("B")); // string2
where the JsonObject could look like
class JsonObject {
private Map<String, String> pairs;
public Map<String, String> getPairs() {
return pairs;
}
}

Gson to HashMap

Is there a way to convert a String containing json to a HashMap, where every key is a json-key and the value is the value of the json-key? The json has no nested values. I am using the Gson lib.
For example, given JSON:
{
"id":3,
"location":"NewYork"
}
resulting HashMap:
<"id", "3">
<"location", "NewYork">
Thanks
Use TypeToken, as per the GSON FAQ:
Gson gson = new Gson();
Type stringStringMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(json, stringStringMap);
No casting. No unnecessary object creation.
If I use the TypeToken solution with a Map<Enum, Object> I get "duplicate key: null".
The best solution for me is:
String json = "{\"id\":3,\"location\":\"NewYork\"}";
Gson gson = new Gson();
Map<String, Object> map = new HashMap<String, Object>();
map = (Map<String, Object>)gson.fromJson(json, map.getClass());
Result:
{id=3.0, location=NewYork}
I like:
private static class MyMap extends HashMap<String,String> {};
...
MyMap map = gson.fromJson(json, MyMap.class);

How to convert hashmap to JSON object in Java

How to convert or cast hashmap to JSON object in Java, and again convert JSON object to JSON string?
You can use:
new JSONObject(map);
Other functions you can get from its documentation
http://stleary.github.io/JSON-java/index.html
Gson can also be used to serialize arbitrarily complex objects.
Here is how you use it:
Gson gson = new Gson();
String json = gson.toJson(myObject);
Gson will automatically convert collections to JSON arrays. Gson can serialize private fields and automatically ignores transient fields.
You can convert Map to JSON using Jackson as follows:
Map<String,Object> map = new HashMap<>();
//You can convert any Object.
String[] value1 = new String[] { "value11", "value12", "value13" };
String[] value2 = new String[] { "value21", "value22", "value23" };
map.put("key1", value1);
map.put("key2", value2);
map.put("key3","string1");
map.put("key4","string2");
String json = new ObjectMapper().writeValueAsString(map);
System.out.println(json);
Maven Dependencies for Jackson :
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
If you are using `JSONObject` library, you can convert map to `JSON` as follows:
JSONObject Library:
import org.json.JSONObject;
Map<String, Object> map = new HashMap<>();
// Convert a map having list of values.
String[] value1 = new String[] { "value11", "value12", "value13" };
String[] value2 = new String[] { "value21", "value22", "value23" };
map.put("key1", value1);
map.put("key2", value2);
JSONObject json = new JSONObject(map);
System.out.println(json);
Maven Dependencies for `JSONObject` :
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
Hope this will help. Happy coding.
Example using json
Map<String, Object> data = new HashMap<String, Object>();
data.put( "name", "Mars" );
data.put( "age", 32 );
data.put( "city", "NY" );
JSONObject json = new JSONObject();
json.putAll( data );
System.out.printf( "JSON: %s", json.toString(2) );
output::
JSON: {
"age": 32,
"name": "Mars",
"city": "NY"
}
You can also try to use Google's GSON.Google's GSON is the best library available to convert Java Objects into their JSON representation.
http://code.google.com/p/google-gson/
You can just enumerate the map and add the key-value pairs to the JSONObject
Method :
private JSONObject getJsonFromMap(Map<String, Object> map) throws JSONException {
JSONObject jsonData = new JSONObject();
for (String key : map.keySet()) {
Object value = map.get(key);
if (value instanceof Map<?, ?>) {
value = getJsonFromMap((Map<String, Object>) value);
}
jsonData.put(key, value);
}
return jsonData;
}
In my case I didn't want any dependancies. Using Java 8 you can get JSON as a string this simple:
Map<String, Object> map = new HashMap<>();
map.put("key", "value");
map.put("key2", "value2");
String json = "{"+map.entrySet().stream()
.map(e -> "\""+ e.getKey() + "\":\"" + String.valueOf(e.getValue()) + "\"")
.collect(Collectors.joining(", "))+"}";
Underscore-java library can convert hash map or array list to json and vice verse.
import com.github.underscore.U;
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("1", "a");
map.put("2", "b");
System.out.println(U.toJson(map));
// {
// "1": "a",
// "2": "b"
// }
}
}
Late to the party but here is my GSON adhoc writer for serializing hashmap. I had to write map of key-value pairs as json string attributes, expect one specific to be integer type. I did not want to create custom JavaBean wrapper for this simple usecase.
GSON JsonWriter class is easy to use serializer class containing few strongly typed writer.value() functions.
// write Map as JSON document to http servlet response
Map<String,String> sd = DAO.getSD(123);
res.setContentType("application/json; charset=UTF-8");
res.setCharacterEncoding("UTF-8");
JsonWriter writer = new JsonWriter(new OutputStreamWriter(res.getOutputStream(), "UTF-8"));
writer.beginObject();
for(String key : sd.keySet()) {
String val = sd.get(key);
writer.name(key);
if (key.equals("UniqueID") && val!=null)
writer.value(Long.parseLong(val));
else
writer.value(val);
}
writer.endObject();
writer.close();
If none of the custom types be needed I could have just use toJson() function. gson-2.2.4.jar library is just under 190KB without any brutal dependencies. Easy to use on any custom servlet app or standalone application without big framework integrations.
Gson gson = new Gson();
String json = gson.toJson(myMap);
If you need use it in the code.
Gson gsone = new Gson();
JsonObject res = gsone.toJsonTree(sqlParams).getAsJsonObject();
This is typically the work of a Json library, you should not try to do it yourself. All json libraries should implement what you are asking for, and you can
find a list of Java Json libraries on json.org, at the bottom of the page.
This solution works with complex JSONs:
public Object toJSON(Object object) throws JSONException {
if (object instanceof HashMap) {
JSONObject json = new JSONObject();
HashMap map = (HashMap) object;
for (Object key : map.keySet()) {
json.put(key.toString(), toJSON(map.get(key)));
}
return json;
} else if (object instanceof Iterable) {
JSONArray json = new JSONArray();
for (Object value : ((Iterable) object)) {
json.put(toJSON(value));
}
return json;
}
else {
return object;
}
}
Better be late than never. I used GSON to convert list of HashMap to string if in case you want to have a serialized list.
List<HashMap<String, String>> list = new ArrayList<>();
HashMap<String,String> hashMap = new HashMap<>();
hashMap.add("key", "value");
hashMap.add("key", "value");
hashMap.add("key", "value");
list.add(hashMap);
String json = new Gson().toJson(list);
This json produces [{"key":"value","key":"value","key":"value"}]
Here my single-line solution with GSON:
myObject = new Gson().fromJson(new Gson().toJson(myHashMap), MyClass.class);
For those using org.json.simple.JSONObject, you could convert the map to Json String and parse it to get the JSONObject.
JSONObject object = (JSONObject) new JSONParser().parse(JSONObject.toJSONString(map));
I found another way to handle it.
Map obj=new HashMap();
obj.put("name","sonoo");
obj.put("age",new Integer(27));
obj.put("salary",new Double(600000));
String jsonText = JSONValue.toJSONString(obj);
System.out.print(jsonText);
Hope this helps.
Thanks.
If you don't really need HashMap then you can do something like that:
String jsonString = new JSONObject() {{
put("firstName", user.firstName);
put("lastName", user.lastName);
}}.toString();
Output:
{
"firstName": "John",
"lastName": "Doe"
}
we use Gson.
Gson gson = new Gson();
Type gsonType = new TypeToken<HashMap>(){}.getType();
String gsonString = gson.toJson(elements,gsonType);
If you are using net.sf.json.JSONObject then you won't find a JSONObject(map) constructor in it. You have to use the public static JSONObject fromObject( Object object ) method. This method accepts JSON formatted strings, Maps, DynaBeans and JavaBeans.
JSONObject jsonObject = JSONObject.fromObject(myMap);
No need for Gson or JSON parsing libraries.
Just using new JSONObject(Map<String, JSONObject>).toString(), e.g:
/**
* convert target map to JSON string
*
* #param map the target map
* #return JSON string of the map
*/
#NonNull public String toJson(#NonNull Map<String, Target> map) {
final Map<String, JSONObject> flatMap = new HashMap<>();
for (String key : map.keySet()) {
try {
flatMap.put(key, toJsonObject(map.get(key)));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
// 2 indentSpaces for pretty printing
return new JSONObject(flatMap).toString(2);
} catch (JSONException e) {
e.printStackTrace();
return "{}";
}
}
I'm using Alibaba fastjson, easy and simple:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>VERSION_CODE</version>
</dependency>
and import:
import com.alibaba.fastjson.JSON;
Then:
String text = JSON.toJSONString(obj); // serialize
VO vo = JSON.parseObject("{...}", VO.class); //unserialize
Everything is ok.
If you are using JSR 374: Java API for JSON Processing ( javax json )
This seems to do the trick:
JsonObjectBuilder job = Json.createObjectBuilder((Map<String, Object>) obj);
JsonObject jsonObject = job.build();
Gson way for a bit more complex maps and lists using TypeToken.getParameterized method:
We have a map that looks like this:
Map<Long, List<NewFile>> map;
We get the Type using the above mentioned getParameterized method like this:
Type listOfNewFiles = TypeToken.getParameterized(ArrayList.class, NewFile.class).getType();
Type mapOfList = TypeToken.getParameterized(LinkedHashMap.class, Long.class, listOfNewFiles).getType();
And then use the Gson object fromJson method like this using the mapOfList object like this:
Map<Long, List<NewFile>> map = new Gson().fromJson(fileContent, mapOfList);
The mentioned object NewFile looks like this:
class NewFile
{
private long id;
private String fileName;
public void setId(final long id)
{
this.id = id;
}
public void setFileName(final String fileName)
{
this.fileName = fileName;
}
}
The deserialized JSON looks like this:
{
"1": [
{
"id": 12232,
"fileName": "test.html"
},
{
"id": 12233,
"fileName": "file.txt"
},
{
"id": 12234,
"fileName": "obj.json"
}
],
"2": [
{
"id": 122321,
"fileName": "test2.html"
},
{
"id": 122332,
"fileName": "file2.txt"
},
{
"id": 122343,
"fileName": "obj2.json"
}
]
}
You can use XStream - it is really handy. See the examples here
package com.thoughtworks.xstream.json.test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class WriteTest {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>();
map.add("1", "a");
map.add("2", "b");
XStream xstream = new XStream(new JettisonMappedXmlDriver());
System.out.println(xstream.toXML(map));
}
}
If you use complex objects, you should apply enableComplexMapKeySerialization(), as stated in https://stackoverflow.com/a/24635655/2914140 and https://stackoverflow.com/a/26374888/2914140.
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
Map<Point, String> original = new LinkedHashMap<Point, String>();
original.put(new Point(5, 6), "a");
original.put(new Point(8, 8), "b");
System.out.println(gson.toJson(original));
Output will be:
{
"(5,6)": "a",
"(8,8)": "b"
}
import org.json.JSONObject;
HashMap<Object, Object> map = new HashMap<>();
String[] list={"Grader","Participant"};
String[] list1={"Assistant","intern"};
map.put("TeachingAssistant",list);
map.put("Writer",list1);
JSONObject jsonObject = new JSONObject(map);
System.out.printf(jsonObject.toString());
// Result: {"TeachingAssistant":["Grader","Participant"],"Writer":["Assistant","intern"]}
You can use Gson.
This library provides simple methods to convert Java objects to JSON objects and vice-versa.
Example:
GsonBuilder gb = new GsonBuilder();
Gson gson = gb.serializeNulls().create();
gson.toJson(object);
You can use a GsonBuilder when you need to set configuration options other than the default. In the above example, the conversion process will also serialize null attributes from object.
However, this approach only works for non-generic types. For generic types you need to use toJson(object, Type).
More information about Gson here.
Remember that the object must implement the Serializable interface.
this works for me :
import groovy.json.JsonBuilder
properties = new Properties()
properties.put("name", "zhangsan")
println new JsonBuilder(properties).toPrettyString()
I faced a similar problem when deserializing the Response from custom commands in selenium. The response was json, but selenium internally translates that into a java.util.HashMap[String, Object]
If you are familiar with scala and use the play-API for JSON, you might benefit from this:
import play.api.libs.json.{JsValue, Json}
import scala.collection.JavaConversions.mapAsScalaMap
object JsonParser {
def parse(map: Map[String, Any]): JsValue = {
val values = for((key, value) <- map) yield {
value match {
case m: java.util.Map[String, _] #unchecked => Json.obj(key -> parse(m.toMap))
case m: Map[String, _] #unchecked => Json.obj(key -> parse(m))
case int: Int => Json.obj(key -> int)
case str: String => Json.obj(key -> str)
case bool: Boolean => Json.obj(key -> bool)
}
}
values.foldLeft(Json.obj())((temp, obj) => {
temp.deepMerge(obj)
})
}
}
Small code description:
The code recursively traverses through the HashMap until basic types (String, Integer, Boolean) are found. These basic types can be directly wrapped into a JsObject. When the recursion is unfolded, the deepmerge concatenates the created objects.
'#unchecked' takes care of type erasure warnings.
First convert all your objects into valid Strings
HashMap<String, String> params = new HashMap<>();
params.put("arg1", "<b>some text</b>");
params.put("arg2", someObject.toString());
Then insert the entire map into a org.json.JSONObject
JSONObject postData = new JSONObject(params);
Now you can get the JSON by simply calling the object's toString
postData.toString()
//{"arg1":"<b>some text<\/b>" "arg2":"object output"}
Create a new JSONObject
JSONObject o = new JSONObject(postData.toString());
Or as a byte array for sending over HTTP
postData.toString().getBytes("UTF-8");

Categories