How to iterate JSON Array and extract each JSON Object from it using GSON?
Solution 1
So you have the JsonArray object with your records, here's what you do to get your functional objects:
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);
Then you iterate through you objects and filter the ones you need. In java 8 you can do this:
List<DataMetrics> result = records.stream().filter(record -> record.name.equals("Client::Sync")).collect(toList());
This approach is converting all objects and iterating after, if exactly this part of code is performance critical, you can still iterate through json and convert only necessary objects (but i doubt that this will be actually faster than described above).
Anyway this is more maintainable and understandable code.
UPDATE:
the same for java 7 will be:
List<DataMetrics> result = new LinkedList<>();
for(DataMetrics record : records){
if(record.name.equals("Client::Sync")){
result.add(record);
}
}
Solution 2
Or if you want to iterate json and parse only required ones heres what you can do:
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
for(JsonElement elem : jsonArrayThatYouHave) {
if (elem.getAsJsonObject().get("name").getAsString().equals("Client::Sync")) {
result.add(gson.fromJson(elem, type));
}
}
but I dont think this is actually faster than the first one because in both cases you are converting json to java functional object with parser and getting JsonArray or anything else. Taking into consideration the fact that both are Googles libs, i assume that parsing from JsonObject to some specific type with gson is way faster than from String (raw json) to the same specific type...
john
Updated on July 20, 2022Comments
-
john almost 2 years
Below is my JSON String which I am getting back by calling from a service API. I have shorten it down by having only three
reportRecords
for the understanding purpose. In general, it might have ~500reportRecords
{ "aggRecords": { "reportRecords": [ { "min": 0, "max": 12, "avg": 0.3699187, "count": 246, "sumSq": 571, "stddev": 1.4779372, "median": 0, "percentileMap": { "95": 4 }, "metricName": "TransactionDuration", "dimensions": { "env": "dev", "pool": "titan", "Name": "PostProcessing", "Type": "PostProcessing" }, "value": 91 }, { "min": 0, "max": 23, "avg": 2.3991289E-4, "count": 1463031, "sumSq": 3071, "stddev": 0.045814946, "median": 0, "percentileMap": { "95": 0 }, "metricName": "TransactionDuration", "dimensions": { "env": "dev", "pool": "titan", "Name": "ResourceContext", "Type": "ResourceContext" }, "value": 351 }, { "min": 0, "max": 1209, "avg": 1.9203402, "count": 7344636, "sumSq": 71832774, "stddev": 2.4683187, "median": 2, "percentileMap": { "95": 4 }, "metricName": "TransactionDuration", "dimensions": { "env": "dev", "pool": "titan", "Name": "Client::Sync", "Type": "Client::Sync" }, "value": 14104200 } ] }, "minRecordsMap": {} }
Now From the above JSON response, I need to extract
reportRecords
whoseName
isClient::Sync
. Meaning, I need to extract belowreportRecords
from the above JSON response only.{ "min": 0, "max": 1209, "avg": 1.9203402, "count": 7344636, "sumSq": 71832774, "stddev": 2.4683187, "median": 2, "percentileMap": { "95": 4 }, "metricName": "TransactionDuration", "dimensions": { "env": "dev", "pool": "titan", "Name": "Client::Sync", "Type": "Client::Sync" }, "value": 14104200 }
And now I need to parse the above
reportRecords
forClient::Sync
to below object -public class DataMetrics { private String pool; private String name; private String type; private String env; private String metricName; private String percentile; private String median; private String stdDev; private String sumSq; private String count; private String avg; private String max; private String min; // getters and setters here }
Above variable, maps like this -
pool is titan name is Client::Sync type is Client::Sync env is dev metricNname is TransactionDuration 95th percentile is 4 median is 2 stdDev is 2.4683187 sumSq is 71832774 count is 7344636 avg is 1.9203402 max is 1209 min is 0
I am using GSON library here and below is what I have tried so far -
private static RestTemplate restTemplate = new RestTemplate(); public static void main(String[] args) { String jsonLine = restTemplate.getForObject("some_url", String.class); System.out.println(jsonLine); // here jsonLine will give me above big JSON String JsonElement jelement = new JsonParser().parse(jsonLine); JsonObject jobject = jelement.getAsJsonObject(); jobject = jobject.getAsJsonObject("aggRecords"); JsonArray jarray = jobject.getAsJsonArray("reportRecords"); // now how do I iterate JsonArray and get each JSON object // and then check "name" property of each object, if "Client::Sync" found, read that object for all properties // and set it using setters. }
Now I am not able to understand how do I iterate JsonArray and extract each JSON object from it?
-
john almost 10 yearsThanks Vach. How would I do this in Java7? I am working Java7 as of now.
-
john almost 10 yearsThanks for the help. I tried this and somehow most of the fields are coming as empty like percentile, name, type, min and few other but some has the data. Do you see anything wrong?
-
vach almost 10 yearsYou just need the same names of Class properties as in json (or specify it with @Qualifier annotation if you dont want to change it)