Deserialize nested JSON array in Java with Gson - java

Something like this. http://jsonlint.com/ says it is valid. Json inside {} simplified for this example.
[[0,{"ok":true},[]],[1,{"ok":false},[]]]
Or with indents:
[
[0, {
"ok": true
},
[]
],
[1, {
"ok": false
},
[]
]
]
This is class for object JSONClass.
public class JSONClass {
boolean ok;
}
If I got it right, this JSON string is array of arrays, latter containing some ID, actual JSON data and empty array. How could I deserialize that?
This doesn't work. I also tried making class with subclasses, didn't work out.
JSONClass[] t = g.fromJson(json, JSONClass[].class);

Well, you have an array of arrays here. Gson will let you convert the JSON objects themselves into the class you want - but you'll have to call gson.fromJson() on each of them separately.
Given String json containing your json, something like this should work:
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
JsonArray jsonArray = jsonParser.parse(json).getAsJsonArray();
for (JsonElement e: jsonArray) {
JSONClass o = gson.fromJson(e.getAsJsonArray().get(1), JSONClass.class);
}
Essentially, the JsonParser will convert your text into a JsonElement, which is the Gson base class for Json arrays and objects. We can iterate over the elements of the JsonArray which we parsed our text into, which in turn is another array of the format [id, object] - and for each element, take the object portion, and deserialize that into a POJO.

Related

How to get something iterable out of a JSON String?

I am trying to parse an Object which is in JSON format like
[{"id": "1", "revisionId":"2"}, {"id":"3", "revisionId":"4"}]
I want to extract the ids to be an iterable array like
["1", "3"]
I have tried using the JSONObject library but it seems when I do this:
JSONObject jsonObject = new JSONObject(obj);
it converts the object into a structure like
{"empty":false}
so using jsonObject.get("id") doesn't work.
Your json string is a json array, not an object, so you can't pass that to JSONObject, but you can use a JSONArray instead.
To get the list of object IDs, you can try something like:
List<String> ids = new JsonArray(obj).toList() // turn the JSONArray into a list
.stream()
.map(JSONObject.class::cast) // cast elements to JSONObjects
.map(json -> json.getString("id")) // extract the id from each object
.collect(Collectors.toList());
Hey you try to parse a json array:
'[{"id": "1", "revisionId":"2"}, {"id":"3", "revisionId":"4"}]'
into a JSONObject. Try something like that:
'{"array": [{"id": "1", "revisionId":"2"}, {"id":"3", "revisionId":"4"}]}'
Then you can access the array with new 'JSONObject(jsonString).getJSONArray("array");'
Let me know if it work for you :-)

How would I convert an element of a JSONObject to a single element array?

I am using org.json.JSONObject and have a json object defined that was converted from XML. I want to be able to convert one of the elements of the JSON to a single element array, but am unclear on how to do this. For example, say I have the following json:
{
"heading": "value",
"numbers": [1,2,3],
"onevalarray": "MyVal"
}
stored in an org.json.JSONObject object. However, I want the element "onevalarray" to be a single element array:
{
"heading": "value",
"numbers": [1,2,3],
"onevalarray": ["MyVal"]
}
How would I accomplish this?
Call the method getJsonArray in the JSONbject object and specify the name of the property in the JSONObject which has the JSONArray in it like this:
Imagine that myJsonObject has this:
{"heading": "value", "numbers": [1,2,3], "onevalarray": "MyVal"}
And you want a JSONArray with onevalarray data. Try it:
JSONArray jsonArray = myJsonObject.getJSONArray("onevalarray");
Once you have the value of the onevalarray in the onevalarray JSONArray then remove the onevalarray in the original array and the put it again in this way:
myJsonObject.remove("onevalarray");
myJsonObject.put("onevalarray", jsonArray);

Using GSON to parse Json into a JAVA Object where the Json Elements may vary

I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:
{
"event0" : {
"a" : "abc",
"b" : "def"
},
"event1" : {
"a" : "ghi",
"b" : "jkl",
"c" : "mno"
}
}
I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:
public class Event {
private String a;
private String b;
private String c;
public Event() {}
}
The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.
Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.
I am fairly new to JSON parsing, and might have missed something in the following answers:
Using Gson to convert Json into Java Object
Mapping JSON into POJO using Gson
Using gson to parse json to java object
Parse JSON into a java object
How to parse a json file into a java POJO class using GSON
I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.
Map map = gson.fromJson(jsonString, Map.class);
Gson automatically do that for you.
So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.
So, in your case, if you write this:
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.
I hope to be helpful! Ask for further informations, if you want to!
EDIT
Note that your json file has not to be .txt but .json instead!
First I believe your JSON should look like this:
{
"events": [
{
"name": "event0",
"a": "abc",
"b": "def"
},
{
"name": "event1",
"a": "abc",
"b": "def",
"c": "mno"
}
]
}
This will need two classes for your model:
public List<Event> events = null;
public class Event {
public String name;
public String a;
public String b;
public String c;
}
And then then with GSON
Events events = gson.fromJson(jsonData, Events.class);
Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it.
https://jsonlint.com/
Or for formate the JSON:
http://jsonprettyprint.com/
Also this website can create the Java classes for you from either a JSON Schema or by using an example file.
http://www.jsonschema2pojo.org/
Try the below code snippet:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());
In the source code of Gson has a very clear explain

How to convert HashMap of Object and String[] to json

Below is my code :
public static void main(String[] args) {
HashMap<HierarchyFilter, String[]> filters = new HashMap();
HierarchyFilter obj = new HierarchyFilter("name1", "type1", "value1");
String[] a = new String[6];
a[0]="String1";
a[1]="String2";
a[2]="String3";
a[3]="String4";
a[4]="String5";
a[5]="String6";
filters.put(obj, a);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(filters);
System.out.println(jsonString);
}
I am using jackson mapper. But my object is not getting converted properly.
Below is the out put what i receive:
{
"com.remote.HierarchyFilter#63bd725" : [ "String1", "String2", "String3", "String4", "String5", "String6" ]
}
I receive the default toString of the Object.
please help
If you are expecting Jackson to map the "com.remote.HierarchyFilter#63bd725" to JSON with the values "name1", "type1", "value1", then you are expecting an INVALID json, which Jackson mapper wouldn't do.
The JSON map data structure is a JSON object data structure, which is a collection of name/value pairs, where the element names must be strings. The JSON map keys must also be strings because JSON map is a JSON object. So, when you try use HierarchyFilter key, it uses the toString method (a string value) of the object to use it as Key.
TO achieve what you need to send to UI, decide on a proper JSON structure contract and then design your Object classes/response objects accordingly.

Parse json with variable key

I just came up with challenging problem.
Below is json response where key is variable (a GUID)
How can I parse it? I've tried Google Gson, but that didn't work.
{
"87329751-7493-7329-uh83-739823748596": {
"type": "work",
"status": "online",
"icon": "landline",
"number": 102,
"display_number": "+999999999"
}
}
If you use Gson, in order to parse your response you can create a custom class representing your JSON data, and then you can use a Map.
Note that a Map<String, SomeObject> is exactly what your JSON represents, since you have an object, containing a pair of string and some object:
{ "someString": {...} }
So, first your class containing the JSON data (in pseudo-code):
class YourClass
String type
String status
String icon
int number
String display_number
Then parse your JSON response using a Map, like this:
Gson gson = new Gson();
Type type = new TypeToken<Map<String, YourClass>>() {}.getType();
Map<String, YourClass> map = gson.fromJson(jsonString, type);
Now you can access all the values using your Map, for example:
String GUID = map.keySet().get(0);
String type = map.get(GUID).getType();
Note: if you only want to get the GUID value, you don't need to create a class YourClass, and you can use the same parsing code, but using a generic Object in the Map, i.e., Map<String, Object>.

Categories