Related
I'm getting this deeply nested JSON response from an api that I have no control,
What should be the best way to get to "generalDetails" and then find the first true value under security, address, account and mobile?
{
"info_code": "201",
"info_description": "info description",
"data": {
"status": "here goes the status",
"failure_data": {
"source": "anySource",
"details": {
"data": {
"server_response": {
"generalDetails": {
"security": {
"isAccountLocked": "false"
},
"address": {
"isAddresExists": "true"
},
"account": {
"accountExists": "true",
"isValidAccount": "true"
},
"mobile": {
"mobileExists": "true"
}
}
}
}
}
}
}
}
My request looks like:
#Autowired
private WebClient.Builder webClientBuilder;
String resp = webClientBuilder.build().get().uri(URL)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class).block();
First, build the model, automatic here https://codebeautify.org/json-to-java-converter.
Then read data with the model
.bodyToMono(MyData.class)
Then decide how you want evaluate the requirement find the first true value under security, address, account and mobile.
What means "first" ? JSON has no natural order without indicating explicity (e.g. field "order": 2).
N.B. "true", "false" of the response are Strings, not booleans.
Once you have the model with data, you may do:
Object firstTrue(GeneralDetails gd) {
// No null checks here
if ("true".equals(gd.getSecurtity().isLockedAccount())) return gd.getSecurtity();
if ("true".equals(gd.getAddress().isAddressExists())) return gd.getAddress();
if ("true".equals(gd.getAccount().isAccountExists()) || "true".equals(gd.getAccount().isAccountValid())) return gd.getAccount();
if ("true".equals(gd.getMobile().isMobileExists())) return gd.getMobile();
return null;
}
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"{" +
" \"info_code\": \"201\"," +
" \"info_description\": \"info description\"," +
" \"data\": {" +
" \"status\": \"here goes the status\"," +
" \"failure_data\": {" +
" \"source\": \"anySource\"," +
" \"details\": {" +
" \"data\": {" +
" \"server_response\": {" +
" \"generalDetails\": {" +
" \"security\": {" +
" \"isAccountLocked\": \"false\"" +
" }," +
" \"address\": {" +
" \"isAddresExists\": \"true\"" +
" }," +
" \"account\": {" +
" \"accountExists\": \"true\"," +
" \"isValidAccount\": \"true\"" +
" }," +
" \"mobile\": {" +
" \"mobileExists\": \"true\"" +
" }" +
" }" +
" }" +
" }" +
" }" +
" }" +
" }" +
"}");
Query
JsonNode node = josson.getNode(
"data.failure_data.details.data.server_response" +
".generalDetails.**.mergeObjects().assort().[*]");
System.out.println(node.toPrettyString());
Output
{
"isAddresExists" : "true"
}
If changed isAddresExists and accountExists to false
" \"generalDetails\": {" +
" \"security\": {" +
" \"isAccountLocked\": \"false\"" +
" }," +
" \"address\": {" +
" \"isAddresExists\": \"false\"" +
" }," +
" \"account\": {" +
" \"accountExists\": \"false\"," +
" \"isValidAccount\": \"true\"" +
" }," +
" \"mobile\": {" +
" \"mobileExists\": \"true\"" +
" }" +
" }" +
Output
{
"isValidAccount" : "true"
}
If you only want the key name
String firstTureKey = josson.getString(
"data.failure_data.details.data.server_response" +
".generalDetails.**.mergeObjects().assort().[*].keys().[0]");
System.out.println(firstTureKey);
Output
isValidAccount
I'm trying to get and print the values of Name and StarRating for each restaurant from the following JSON of which I've taken a snippet (there is more above this, however this is the relevant bit I'm trying to extract. Full link is available here API):
Restaurants": [
{
"Id": 89024,
"Name": "Regina Pizza",
"UniqueName": "regina-pizza-new-croydon",
"Address": {
"City": "Croydon",
"FirstLine": "309 Lower Addiscombe Road",
"Postcode": "CR0 6RF",
"Latitude": 51.382231,
"Longitude": -0.069915
},
"City": "Croydon",
"Postcode": "CR0 6RF",
"Latitude": 0.0,
"Longitude": 0.0,
"Rating": {
"Count": 561,
"Average": 5.18,
"StarRating": 5.18
}
I have the following method to get the data:
public static String parse(String responseBody) {
JSONArray restaurants = new JSONArray(responseBody);
for (int i = 0; i < restaurants.length(); i++) {
JSONObject restaurant = restaurants.getJSONObject(i);
String name = restaurant.getString("Name");
int rating = restaurant.getInt("StarRating");
System.out.println("Restaurant: " + name + " Rating: " + rating);
}
return null;
}
When running the code, I get an error indicating a JSONArray must start with '['.
I've tried to find similar examples of nested JSON, but I'm unable to find a relevant example.
Undercore-java will help.
String json = "{\"Restaurants\": [\n" +
"{\n" +
" \"Id\": 89024,\n" +
" \"Name\": \"Regina Pizza\",\n" +
" \"UniqueName\": \"regina-pizza-new-croydon\",\n" +
" \"Address\": {\n" +
" \"City\": \"Croydon\",\n" +
" \"FirstLine\": \"309 Lower Addiscombe Road\",\n" +
" \"Postcode\": \"CR0 6RF\",\n" +
" \"Latitude\": 51.382231,\n" +
" \"Longitude\": -0.069915\n" +
" },\n" +
" \"City\": \"Croydon\",\n" +
" \"Postcode\": \"CR0 6RF\",\n" +
" \"Latitude\": 0.0,\n" +
" \"Longitude\": 0.0,\n" +
" \"Rating\": {\n" +
" \"Count\": 561,\n" +
" \"Average\": 5.18,\n" +
" \"StarRating\": 5.18\n" +
" }" +
"}]}";
U.<List<Map<String, Object>>>get(U.fromJsonMap(json), "Restaurants").forEach(
restaurant -> System.out.println(restaurant.get("Name") + " "
+ U.get(restaurant, "Rating.StarRating"))
);
// output
// Regina Pizza 5.18
Consider using Java's JsonPath
And do something like (might need some tweaking)
Restaurants[name][StarRating]
I want to consume an api that returns a json like this one:
{
"startDate": "2019-06-23T16:07:21.205Z",
"endDate": "2019-07-24T16:07:21.205Z",
"status": "Complete",
"usages": [
{
"name": "PureCloud Edge Virtual Usage",
"resources": [
{
"name": "Edge01-VM-GNS-DemoSite01 (1f279086-a6be-4a21-ab7a-2bb1ae703fa0)",
"date": "2019-07-24T09:00:28.034Z"
},
{
"name": "329ad5ae-e3a3-4371-9684-13dcb6542e11",
"date": "2019-07-24T09:00:28.034Z"
},
{
"name": "e5796741-bd63-4b8e-9837-4afb95bb0c09",
"date": "2019-07-24T09:00:28.034Z"
}
]
},
{
"name": "PureCloud for SmartVideo Add-On Concurrent",
"resources": [
{
"name": "jpizarro#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "jaguilera#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "dcortes#gns.com.co",
"date": "2019-07-15T15:06:09.203Z"
}
]
},
{
"name": "PureCloud 3 Concurrent User Usage",
"resources": [
{
"name": "jpizarro#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "jaguilera#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "dcortes#gns.com.co",
"date": "2019-07-15T15:06:09.203Z"
}
]
},
{
"name": "PureCloud Skype for Business WebSDK",
"resources": [
{
"name": "jpizarro#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "jaguilera#gns.com.co",
"date": "2019-06-25T04:54:17.662Z"
},
{
"name": "dcortes#gns.com.co",
"date": "2019-07-15T15:06:09.203Z"
}
]
}
],
"selfUri": "/api/v2/billing/reports/billableusage"
}
I have to count the amount of name in the last level. Looking on the web I´ve found a library and I just tried to adapt the example, but I have some doubts: one is that it starts with a string, not the route of the json file I have to test. I´ve put it in there manually, buy Eclipse added a lot of: /
When I try to run this:
String jsonString = "{\r\n" +
" \"startDate\": \"2019-06-23T16:07:21.205Z\",\r\n" +
" \"endDate\": \"2019-07-24T16:07:21.205Z\",\r\n" +
" \"status\": \"Complete\",\r\n" +
" \"usages\": [\r\n" +
" {\r\n" +
" \"name\": \"PureCloud Edge Virtual Usage\",\r\n" +
" \"resources\": [\r\n" +
" {\r\n" +
" \"name\": \"Edge01-VM-GNS-DemoSite01 (1f279086-a6be-4a21-ab7a-2bb1ae703fa0)\",\r\n" +
" \"date\": \"2019-07-24T09:00:28.034Z\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"329ad5ae-e3a3-4371-9684-13dcb6542e11\",\r\n" +
" \"date\": \"2019-07-24T09:00:28.034Z\"\r\n" +
" }, \r\n" +
" {\r\n" +
" \"name\": \"e5796741-bd63-4b8e-9837-4afb95bb0c09\",\r\n" +
" \"date\": \"2019-07-24T09:00:28.034Z\"\r\n" +
" }\r\n" +
" ]\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"PureCloud for SmartVideo Add-On Concurrent\",\r\n" +
" \"resources\": [\r\n" +
" {\r\n" +
" \"name\": \"jpizarro#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"jaguilera#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" }, \r\n" +
" {\r\n" +
" \"name\": \"dcortes#gns.com.co\",\r\n" +
" \"date\": \"2019-07-15T15:06:09.203Z\"\r\n" +
" }\r\n" +
" ]\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"PureCloud 3 Concurrent User Usage\",\r\n" +
" \"resources\": [\r\n" +
" {\r\n" +
" \"name\": \"jpizarro#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"jaguilera#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" }, \r\n" +
" {\r\n" +
" \"name\": \"dcortes#gns.com.co\",\r\n" +
" \"date\": \"2019-07-15T15:06:09.203Z\"\r\n" +
" }\r\n" +
" ]\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"PureCloud Skype for Business WebSDK\",\r\n" +
" \"resources\": [\r\n" +
" {\r\n" +
" \"name\": \"jpizarro#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"jaguilera#gns.com.co\",\r\n" +
" \"date\": \"2019-06-25T04:54:17.662Z\"\r\n" +
" }, \r\n" +
" {\r\n" +
" \"name\": \"dcortes#gns.com.co\",\r\n" +
" \"date\": \"2019-07-15T15:06:09.203Z\"\r\n" +
" }\r\n" +
" ]\r\n" +
" }\r\n" +
" ],\r\n" +
" \"selfUri\": \"/api/v2/billing/reports/billableusage\"\r\n" +
"}\r\n" +
"";
int cantidadDeLicencias = 0;
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray usages = jsonObject.getJSONArray("usages");
System.out.println("usages " + usages);
for (int i = 0; i < usages.length(); i++) {
JSONArray resources = jsonObject.getJSONArray("resources");
for (int j = 0; j < resources.length(); j++) {
JSONArray names = jsonObject.getJSONArray("name");
cantidadDeLicencias = cantidadDeLicencias + names.length();
//String name = jsonObject.getJSONObject(j).getString("name");
}
}
System.out.println("Cantidad de licencias" + cantidadDeLicencias);
An error comes out: JSONObject["resources"] not found.
If the program would work, what changes I have to make cause, the api returns a json, you know, without all those: /. So this library is going to be useful?
Update
Now it works
int cantidadDeLicencias = 0;
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray usages = jsonObject.getJSONArray("usages");
System.out.println("usages " + usages);
for (int i = 0; i < usages.length(); i++) {
JSONObject innerTemp = usages.getJSONObject(i);
JSONArray resources = innerTemp.getJSONArray("resources");
//JSONArray resources = usages.getJSONArray("resources");
for (int j = 0; j < resources.length(); j++) {
String names = resources.getJSONObject(j).getString("name");
cantidadDeLicencias = cantidadDeLicencias + 1;
//String name = jsonObject.getJSONObject(j).getString("name");
}
}
System.out.println("Cantidad de licencias " + cantidadDeLicencias);
What should I do with the json? cause, here it has a lot of: / and the api doesn´t return that?
resources is inside a JSONObject, not directly inside the JSONArray.
Access it like this:
JSONArray usages = jsonObject.getJSONArray("usages");
for (int i = 0; i < usages.length(); i++) {
JSONObject innerTemp = usages.getJSONObject(i);
JSONArray resources = innerTemp.getJSONArray("resources");
// more code here
}
I have a dynamic JSON Array and I need to filter the JSON based on "isCalculatedField": false.
[{
"id": "CX.VOEFAIL.CREATEDT",
"description": "Task Management - Voe Fail Review Create Date",
"format": "STRING",
"maxLength": 40,
"modelPath": "Loan.CustomFields[(FieldName == 'CX.VOEFAIL.CREATEDT')].StringValue",
"isCalculatedField": false
},
{
"id": "CX.VOEFAIL.TASKCNT",
"description": "Task Management - VOE Fail Review Task Count",
"format": "INTEGER",
"maxLength": 0,
"modelPath": "Loan.CustomFields[(FieldName == 'CX.VOEFAIL.TASKCNT')].StringValue",
"isCalculatedField": false
},
{
"id": "CX.YEARS.AT.EMPLOYER",
"description": "Years employed",
"format": "DROPDOWNLIST",
"maxLength": 0,
"options": [
"Yes"
],
"modelPath": "Loan.CustomFields[(FieldName == 'CX.YEARS.AT.EMPLOYER')].StringValue",
"isCalculatedField": true
},
{
"id": "CX.YEARS.AT.RESIDENCE",
"description": "Years at residence",
"format": "DROPDOWNLIST",
"maxLength": 0,
"options": [
"Yes"
],
"modelPath": "Loan.CustomFields[(FieldName == 'CX.YEARS.AT.RESIDENCE')].StringValue",
"isCalculatedField": true
}]
How can I get sub JSON list containing "isCalculatedField" : false??
I have this JSON data in String.
Use JSON-P:
import java.io.StringReader;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
public class Playground {
public static void main(String[] args) {
String json = "[{\n"
+ " \"id\": \"CX.VOEFAIL.CREATEDT\",\n"
+ " \"description\": \"Task Management - Voe Fail Review Create Date\",\n"
+ " \"format\": \"STRING\",\n"
+ " \"maxLength\": 40,\n"
+ " \"modelPath\": \"Loan.CustomFields[(FieldName == 'CX.VOEFAIL.CREATEDT')].StringValue\",\n"
+ " \"isCalculatedField\": false\n"
+ "},\n"
+ "{\n"
+ " \"id\": \"CX.VOEFAIL.TASKCNT\",\n"
+ " \"description\": \"Task Management - VOE Fail Review Task Count\",\n"
+ " \"format\": \"INTEGER\",\n"
+ " \"maxLength\": 0,\n"
+ " \"modelPath\": \"Loan.CustomFields[(FieldName == 'CX.VOEFAIL.TASKCNT')].StringValue\",\n"
+ " \"isCalculatedField\": false\n"
+ "},\n"
+ "{\n"
+ " \"id\": \"CX.YEARS.AT.EMPLOYER\",\n"
+ " \"description\": \"Years employed\",\n"
+ " \"format\": \"DROPDOWNLIST\",\n"
+ " \"maxLength\": 0,\n"
+ " \"options\": [\n"
+ " \"Yes\"\n"
+ " ],\n"
+ " \"modelPath\": \"Loan.CustomFields[(FieldName == 'CX.YEARS.AT.EMPLOYER')].StringValue\",\n"
+ " \"isCalculatedField\": true\n"
+ "},\n"
+ "{\n"
+ " \"id\": \"CX.YEARS.AT.RESIDENCE\",\n"
+ " \"description\": \"Years at residence\",\n"
+ " \"format\": \"DROPDOWNLIST\",\n"
+ " \"maxLength\": 0,\n"
+ " \"options\": [\n"
+ " \"Yes\"\n"
+ " ],\n"
+ " \"modelPath\": \"Loan.CustomFields[(FieldName == 'CX.YEARS.AT.RESIDENCE')].StringValue\",\n"
+ " \"isCalculatedField\": true\n"
+ "}]";
JsonReader reader = Json.createReader(new StringReader(json));
JsonArray array = reader.readArray();
for (int i = 0; i < array.size(); i++) {
JsonObject obj = array.getJsonObject(i);
if (!obj.getBoolean("isCalculatedField")) {
System.out.println(obj.toString() + " is not calculated");
}
}
}
}
Output:
{"id":"CX.VOEFAIL.CREATEDT","description":"Task Management - Voe Fail Review Create Date","format":"STRING","maxLength":40,"modelPath":"Loan.CustomFields[(FieldName == 'CX.VOEFAIL.CREATEDT')].StringValue","isCalculatedField":false} is not calculated
{"id":"CX.VOEFAIL.TASKCNT","description":"Task Management - VOE Fail Review Task Count","format":"INTEGER","maxLength":0,"modelPath":"Loan.CustomFields[(FieldName == 'CX.VOEFAIL.TASKCNT')].StringValue","isCalculatedField":false} is not calculated
You can use DSM library. By using it you can filter JSON while you reading JSON data.
You will define a YAML file that contains definitions of your mappings
Mapping File:
result:
type: array # result is array
path: /
filter: self.data.isCalculatedField # filter by isCalculatedField
fields:
id:
description:
modelPath:
isCalculatedField: boolean
format:
Use DSM to filter data.
DSM dsm=new DSMBuilder(new File("path/to/config.yaml")).create();
Object object=dsm.toObject(new File("path/to/data.json");
Here is the result:
[ {
"id" : "CX.YEARS.AT.EMPLOYER",
"description" : "Years employed",
"format" : "DROPDOWNLIST",
"modelPath" : "Loan.CustomFields[(FieldName == 'CX.YEARS.AT.EMPLOYER')].StringValue",
"isCalculatedField" : true
}, {
"id" : "CX.YEARS.AT.RESIDENCE",
"description" : "Years at residence",
"format" : "DROPDOWNLIST",
"modelPath" : "Loan.CustomFields[(FieldName == 'CX.YEARS.AT.RESIDENCE')].StringValue",
"isCalculatedField" : true
}, {
"id" : "CX.YEARS.AT.RESIDENCE",
"description" : "Years at residence",
"format" : "DROPDOWNLIST",
"modelPath" : "Loan.CustomFields[(FieldName == 'CX.YEARS.AT.RESIDENCE')].StringValue",
"isCalculatedField" : true
} ]
I want to convert my json string to string array. My JSON string is having two parameters "href" and "name". I want to create List of string of values of "name" parameter using java. I am using NetBeans for my application. please help me out to resolve this issue. I am getting error as
Exception in thread "AWT-EventQueue-0" org.json.JSONException: A JSONArray text must start with '[' at 1 [character 2 line 1]
JSONArray arr = new JSONArray(response);
List<String> list = new ArrayList<String>();
for(int i = 0; i < arr.length(); i++){
list.add(arr.getJSONObject(i).getString("name"));
System.out.println(arr.getJSONObject(i).getString("name"));
}
This is my JSON string
[
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/1",
"name": "analogValue_1"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/9",
"name": "analogValue_9"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/2",
"name": "analogValue_2"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/8",
"name": "analogValue_8"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/7",
"name": "analogValue_7"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/3",
"name": "analogValue_3"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/6",
"name": "analogValue_6"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/5",
"name": "analogValue_5"
},
{
"href": "\/api\/rest\/v1\/protocols\/bacnet\/local\/objects\/analog-value\/4",
"name": "analogValue_4"
}
]
Fix your json. 1. Change square brackets to curly brackets. 2. Each dictionary inside of your json is a value which must have a corresponding key. You code should look like this:
public static void main(String[] args) {
String myJSON = "{data_0:\n"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/1\",\n"
+ " \"name\": \"analogValue_1\"\n"
+ " },\n data_1:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/9\",\n"
+ " \"name\": \"analogValue_9\"\n"
+ " },\n data_2:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/2\",\n"
+ " \"name\": \"analogValue_2\"\n"
+ " },\n data_3:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/8\",\n"
+ " \"name\": \"analogValue_8\"\n"
+ " },\n data_4:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/7\",\n"
+ " \"name\": \"analogValue_7\"\n"
+ " },\n data_5:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/3\",\n"
+ " \"name\": \"analogValue_3\"\n"
+ " },\n data_6:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/6\",\n"
+ " \"name\": \"analogValue_6\"\n"
+ " },\n data_7:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/5\",\n"
+ " \"name\": \"analogValue_5\"\n"
+ " },\n data_8:"
+ " {\n"
+ " \"href\": \"\\/api\\/rest\\/v1\\/protocols\\/bacnet\\/local\\/objects\\/analog-value\\/4\",\n"
+ " \"name\": \"analogValue_4\"\n"
+ " }\n"
+ "}";
JSONObject jsonObject = new JSONObject(myJSON);
System.out.println("jsonObject: " + jsonObject.toString());
List<String> list = new ArrayList<String>();
System.out.println("jsonObject length: " + jsonObject.length());
for (int i = 0; i < jsonObject.length(); i++) {
list.add(jsonObject.getJSONObject("data_" + i).toString());
System.out.println(jsonObject.getJSONObject("data_" + i));
}
}
I added keys from data_0 to data_8. Then you create a list. Probably that does not exactly solve your problem, but least gives an idea where you're making a mistake.
From your comment we can see that you're using okhttp3.internal.http.RealResponseBody. Since the toString() method is not overwritten, the default implementation is used which is why System.out.println(response.body().toString()); prints okhttp3.internal.http.RealResponseBody#66cdc1bd.
To get the actual raw response use the string() method:
JSONArray arr = new JSONArray(responseBody.string());
According to the documentation (RealResponseBody extends ResponseBody):
String string()
Returns the response as a string decoded with the charset of the Content-Type header.
This also has already been discussed here by the way.