Reputation: 11679
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 ~500 reportRecords
{
"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
whose Name
is Client::Sync
. Meaning, I need to extract below reportRecords
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
for Client::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
}
So after serializing, above object should look 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");
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);
List<DataMetrics> result = new LinkedList<>();
for(DataMetrics record : records){
if(record.name.equals("Client::Sync")){
result.add(record);
}
}
}
But for some reason, some fields in the DataMetrics shows me the data but some fields are coming empty so that makes me think something is wrong in my above code or my DataMetrics class is not right?
Upvotes: 0
Views: 602
Reputation: 3118
Generally, for nested objects like dimensions
you'll declare another POJO for it
class DataMetrics{
private String min;
private String max;
private String avg;
/*Insert other members*/
private Dimensions dimensions;
public boolean isClientSync(){
return "Client::Sync".equals(dimensions.Name);
}
private class Dimensions{
private String env;
private String pool;
private String Name;
}
}
Tested:
public void test() {
String json = "[{\"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}]";
final Gson gson = new Gson();
final Type type = new TypeToken<List<DataMetrics>>() {}.getType();
final List<DataMetrics> records = gson.fromJson(json, type);
Assert.assertTrue(records.get(0).isClientSync());
}
For percentileMap
you'll want an actual map
private Map<String, Integer> percentileMap;
Also note the member variable names should match the JSON property name exactly
stdDev
=> stddev
name
=> Name
percentile
=> percentileMap
Upvotes: 1