How to parse following json using Gson? - java

I have seen similar questions about parsing json with dynamic keys, but could not figure out how to parse the following json:
{
"unknown":
{
"id":3980715,
"name":"namename",
"profileIconId":28,
"revisionDate":1451936993000
}
}
Here, the "unknown" key is dynamic, it can be anything. We do not know what it is.
I tried the following class:
public class MyResponseClass {
private Map<String, Object> myResponse;
//Getter and setter
}
But myResponse becomes null after using gson like the following:
return gson.fromJson(response, MyResponseClass.class);
So, how can i do this?
Thanks.

I could manage to parse it like the following:
Type mapType = new TypeToken<Map<String, MyResponseClass>>() {}.getType();
Map<String, MyResponseClass> map = gson.fromJson(response, mapType);
and then iterated over map to get what I want.

Add an annotation to the field myResponse.
public class MyResponseClass {
#SerializedName("unknown")
private Map<String, Object> myResponse;
//Getter and setter
}

Try this:
// String jsonStr = ...;
Gson gson = new Gson();
Map<String, Object> jsonData = new HashMap<String, Object>();
jsonData = (Map<String, Object>)gson.fromJson(jsonStr, Object.class);
Your JSON data will be stored in Map<String, Object> (which is the simpliest way to store JSON data in Java).
So in this map at unknown key you will have another map with id, name etc.

Related

ObjectMapper using com.jsoniter library

I have a Map<String, Object> map that was deserialized from a simple JSON string {"field1":"val1", "field2":"val2", "isReal":true}. I am trying to construct a Java object MyObject with the above fields.
I can do it using com.fasterxml.jackson.databind.ObjectMapper like so:
public static MyObject load(Map<String, Object> map) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(new ObjectMapper().writeValueAsString(map), MyObject.class);
}
I was wondering if anyone knows how to do the same using com.jsoniter library?
I have tried to use JsonIterator.deserialize, but that doesn't take a Map as input.
I have also seen ReflectionEncoderFactory usage on the library website, but I don't fully grasp as to how I would use it to construct an object MyObject
As per #Scary Wombat's explanation:
First it is necessary to convert the Map back to JSON string and then convert the JSON string to an object:
public static MyObject load(Map<String, Object> map) throws IOException {
return JsonIterator.deserialize(JsonStream.serialize(map), MyObject.class);
}
JsonStream.serialize(map) is the same new ObjectMapper().writeValueAsString(map)

Add a parent node to Json output in java

I have converted some info to Json format using Jackson in Java. Below is the output I get
[{"lat":45.9,"lon":10.9,"title":"Title A1","html":"<h3>Content A1</h3>","icon":"http://maps.google.com/mapfiles/markerA.png"},{"lat":44.8,"lon":1.7,"title":"Title B1","html":"<h3>Content B1</h3>","icon":"http://maps.google.com/mapfiles/markerB.png","show_infowindow":false},{"lat":51.5,"lon":-1.1,"title":"Title C1","html":"<h3>Content C1</h3><p>Lorem Ipsum..</p>","zoom":8,"icon":"http://maps.google.com/mapfiles/markerC.png"}]
My question is how can I get it in the below format, basically adding the Json to a root node which called locations
{"locations":[{"lat":45.9,"lon":10.9,"title":"Title A1","html":"<h3>Content A1</h3>","icon":"http://maps.google.com/mapfiles/markerA.png"},{"lat":44.8,"lon":1.7,"title":"Title B1","html":"<h3>Content B1</h3>","icon":"http://maps.google.com/mapfiles/markerB.png","show_infowindow":false},{"lat":51.5,"lon":-1.1,"title":"Title C1","html":"<h3>Content C1</h3><p>Lorem Ipsum..</p>","zoom":8,"icon":"http://maps.google.com/mapfiles/markerC.png"}]}
You may wrap the array into a JSONObject like so
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<String, Object>();
String json = jsonArray.toString();
map.put("locations", json);
json = mapper.writeValueAsString(map);
you can achieve this by following changes.
Let's Assume, your JSON will be created based upon Bean.java class likewise,
[{"lat":45.9,"lon":10.9,"title":"Title A1","html":"<h3>Content A1</h3>","icon":"http://maps.google.com/mapfiles/markerA.png"},{"lat":44.8,"lon":1.7,"title":"Title B1","html":"<h3>Content B1</h3>","icon":"http://maps.google.com/mapfiles/markerB.png","show_infowindow":false},{"lat":51.5,"lon":-1.1,"title":"Title C1","html":"<h3>Content C1</h3><p>Lorem Ipsum..</p>","zoom":8,"icon":"http://maps.google.com/mapfiles/markerC.png"}]
Now, As per your new requirement, you want something likewise,
{"locations":[{"lat":45.9,"lon":10.9,"title":"Title A1","html":"<h3>Content A1</h3>","icon":"http://maps.google.com/mapfiles/markerA.png"},{"lat":44.8,"lon":1.7,"title":"Title B1","html":"<h3>Content B1</h3>","icon":"http://maps.google.com/mapfiles/markerB.png","show_infowindow":false},{"lat":51.5,"lon":-1.1,"title":"Title C1","html":"<h3>Content C1</h3><p>Lorem Ipsum..</p>","zoom":8,"icon":"http://maps.google.com/mapfiles/markerC.png"}]}
So, in this case you need to create one more class, let's say it's SuperBean.java then it should be likewise,
public class SuperBean {
private Bean [] locations;
public Bean[] getBean() {
return locations;
}
public void setBean(Bean[] locations) {
this.locations = locations;
}
}
So, your JSON will be created likewise,
{"locations":[......]} // as per your requirement.

Conversion between JSON with wrapped structure and pojo with flattended structure

I have a JSON structure that incorporates a wrapping level that I don't have in my POJOs. Like so:
JSON:
{
"category1": {
"cat1Prop1": "c1p1",
"cat1Prop2": "c1p2",
"cat1Prop3": "c1p3"
},
"category2": {
"cat2Prop1": "c2p1",
"cat2Prop2": "c2p2"
},
"category3": {
"cat3Prop1": "c3p1",
"cat3Prop2": "c3p2",
"cat3Prop3": "c3p3"
},
"category4": {
"cat4Prop1": "c4p1"
}
}
POJO:
public class MyPojo {
private String cat1Prop1;
private String cat1Prop2;
private String cat1Prop3;
private String cat2Prop1;
private String cat2Prop2;
private String cat3Prop1;
private String cat3Prop2;
private String cat3Prop3;
private String cat4Prop1;
// Getters / setters, etc...
}
As you can see, the JSON have a "category" level (that for different reasons I don't want to have in my Pojo).
I'm looking for a way to use Jackson for serializaion/deserialization to handle this in a smooth way.
I'm aware that Jackson has a #JsonUnwrapped annotation that kind of handles the opposite. I'm also aware that there is a feature request for a "#JsonWrapped" annotation that I think would solve my case.
Thankful for any input or help regarding this, as I have been looking around quite a bit. Also, any suggestions on how this could be accomplished using any other library (like gson, flexjson, etc) is also interesting.
You can try with this algorithm:
Read JSON as Map.
Flatten map
Use ObjectMapper to convert Map into POJO.
Implementation could looks like this:
ObjectMapper mapper = new ObjectMapper();
Map<String, Map<String, String>> map = mapper.readValue(new File("X:/test.json"), Map.class);
Map<String, String> result = new HashMap<String, String>();
for (Entry<String, Map<String, String>> entry : map.entrySet()) {
result.putAll(entry.getValue());
}
System.out.println(mapper.convertValue(result, MyPojo.class));

Sending JSON with arbitrary key values using REST service (Jersey/Jackson)

I want to send something like this from the client to the rest service
jsonObj =
{
"info" : {
"field1" : "val1"..
.....
"fieldN" : "valN"..
}
}
And I am not sure how can I handle this using a rest service using Jersey and Jackson in Java
I do not want to create a new info class with using Jackson properties with N field as they are going to change always. I just want to grab the jsonObject which is inside the jsonObject and operate on that as JsonObject.
Any thoughts ?
Assuming you have a root object that you are reading the result into, you could define docInfo as a Map<String, Object> within your jsonObj. This will probably work, but I can't give it a go presently.
If you don't have a root object you can just use a Map<String, Object> as your root object and play with it from there. That Map could contain other maps for nested json objects.
Yes, use a wrapper object with an embedded map, as #digitialjoel suggested. This is a concrete example:
class DocInfo {
private Map<String, Object> docInfo;
public DocInfo() {
super();
}
public DocInfo(final Map<String, Object> docInfo) {
super();
this.docInfo = docInfo;
}
// Getters, setters
}
final Map<String, Object> data = new LinkedHashMap<String, Object>(4);
data.put("field1", "value1");
data.put("field2", "value2");
data.put("field3", "value3");
data.put("field4", "value4");
final DocInfo info = new DocInfo(data);
final ObjectMapper mapper = new ObjectMapper();
final String json = mapper.writeValueAsString(info);
System.out.println(json);
Output:
{"docInfo":{"field1":"value1","field2":"value2","field3":"value3","field4":"value4"}}

Merge multiple Collection<String> into one JSON String using GSON

Is there a way to merge different String-Collections into one JSON 'String'?
I would like to have a JSON String that looks like this:
{"vendor":[Sun, HP, IBM],"product":[bla, bla, bla],"availability":[high, mid, low],"capacity":[bla, bla, bla], ...}
This is a part of my Java Code:
Collection<String> vendor = bh.getAllVendors();
Collection<String> product = bh.getProductsForVendor(vendor);
Collection<String> availability = bh.getAllAvailabilities();
Collection<String> capacity = bh.getCapacityForVendor(vendor);
Collection<String> signaling = bh.getSignalingForVendor(vendor);
Collection<String> backup = bh.getBackupForVendor(vendor);
Gson gson = new Gson();
Any help would be appreciated.
It would be easiest if you add them to a map:
Gson gson = new Gson();
Map<String, Collection<String>> map = new HashMap<>();
map.put("vendor", vendor);
map.put("product", product);
//etc
System.out.println(gson.toJson(map));
produces
{"product":["bla","bla","bla"],"vendor":["Sun","IBM","HP"]}
Create a new class:
Class MyJSONObject
{
Collection<String> vendor;
Collection<String> product;
Collection<String> availability;
//...
//...
}
Then assign your data to those attributes in an instance of MyJSONObject.
Then serialize that instance:
gson.toJson (myJSONObjectInstance);
Read the 'Object Examples' section of this GSON documentation.

Categories