I am consuming Thirdparty jsonString, I am trying to parse the json but sometimes JSON object "RadarReports" is an list and sometimes it object.
{"RadarReports": {
"executionTime": "135",
"RadarReport": {
"abc": "1116591",
"name": "abc",
"id": "2019050311582056119",
"ownerId": "xyz"
},
"size" :"1"
}}
=================
{"RadarReports": {
"executionTime": "113",
"RadarReport": [
{
"abc": "1116591",
"name": "abc",
"id": "2019050311582056119",
"ownerId": "xyz"
},
{
"abc": "1116591",
"name": "abc",
"id": "2019050311582056119",
"ownerId": "xyz"
},
]
"size" : "2"
}}
I tried below to parse but failing when single object came into picture, need to accept both single and list of objects.
@Data
public class Radarreports {
private int size;
private ArrayList<RadarreportSet> RadarReportSet;
private ArrayList<RadarReport> RadarReport;
}
@Data
public
class ReportsResponse {
Radarreports RadarReports;
}
URL url = new URL(queryUrl);
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
Gson gson = new GsonBuilder().create();
ReportsResponse radarReports = gson.fromJson(br, ReportsResponse.class);
You could solve this with a custom TypeAdapterFactory
which creates an adapter which first peeks at the type of the JSON data and then adds special handling where the JSON object is not wrapped in an JSON array:
// Only intended for usage with @JsonAdapter
class SingleObjectOrListAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
// Note: Cannot use getDelegateAdapter due to https://github.com/google/gson/issues/1028
TypeAdapter<T> listAdapterDelegate = gson.getAdapter(type);
TypeAdapter<JsonObject> jsonObjectAdapter = gson.getAdapter(JsonObject.class);
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
listAdapterDelegate.write(out, value);
}
@Override
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.BEGIN_OBJECT) {
// Wrap JSON object in a new JSON array before parsing it
JsonObject jsonObject = jsonObjectAdapter.read(in);
JsonArray jsonArray = new JsonArray();
jsonArray.add(jsonObject);
return listAdapterDelegate.fromJsonTree(jsonArray);
} else {
return listAdapterDelegate.read(in);
}
}
};
}
}
The factory can then be specified for the affected field with @JsonAdapter
:
@JsonAdapter(SingleObjectOrListAdapterFactory.class)
private ArrayList<RadarReport> RadarReport;