3 levels Json how can I make a count inside - java

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
}

Related

Deeply nested JSON response from third party

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

Spring query convert to a nested JSON structure

I'm new to spring and Java and trying to figure out how to go about formatting the json response into the desired structure.
I have a spring query that's returning 2 columns from a table like below which are really the key and values I need for the json structure:
Names
Values
Car
Toyota
Bike
Schwinn
Scooter
Razor
A0
11
A1
12
A2
13
B0
2000
B1
4000
B2
22000
The current json output from the controller is this:
[{
"names": "Car",
"values": "Toyota"
},
{
"names": "Bike",
"values": "Schwinn"
},
{
"names": "Scooter",
"values": "Razor"
},
{
"names": "A0",
"values": "11"
},
{
"names": "A1",
"values": "12"
},
{
"names": "A2",
"values": "13"
},
{
"names": "B0",
"values": "2000"
},
{
"names": "B1",
"values": "4000"
},
{
"names": "B2",
"values": "22000"
}
]
And the desired json format is this where the table column names are removed and instead json structure is created using the names column for the keys:
{
"Car": "Toyota",
"Bike": "Schwinn",
"Scooter": "Razor",
"Data": [{
"A0": "11",
"B0": "2000"
}, {
"A1": "12",
"B1": "4000"
}, {
"A2": "13",
"B2": "22000"
}]
}
Repository
#Query (value = "Select names, values ... :id")
List<Data> findData(#Param("id") Long id) ;
interface Data {
String getnames();
String getvalues();
}
Service
public List<Data> getData(Long id) {return repo.findData(id);}
Controller
#GetMapping("/getdata/{id}")
public ResponseEntity<List<Data>> getData(#PathVariable Long id) {
List<Data> c = service.getData(id);
return new ResponseEntity<>(c, HttpStatus.OK);
}
It seems that I need to process the result set and need to loop through them to create the desired structure but not sure how to proceed with that, or perhaps there is an easier way to get to the desired structure. Any guidance would be appreciated.
So return a ResponseEntity<Map<String, Object>> instead of a List to simulate a Json object.
List<Data> c = service.getData(id);
Map<String, Object> map = new HashMap<>();
map.put("Key", "Value");
map.put("Car", c.get(0).getvalues());
map.put("Entire List", c);
return new ResponseEntity<>(c, HttpStatus.OK);
Obviously you'll have to write your own logic but it should be pretty straight forward. Or, even better, consider making a class for the object returned if you're going to be using it a lot, and just return ResponseEntity< YourCustomObject >
This looks a bit complicated, I think you should set the primary key association for values like A0 B0
import com.black_dragon.utils.JacksonUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.groupingBy;
/**
* #author black_dragon
* #version V1.0
* #Package com.black_dragon.swing
* #date 2022/9/6 10:35
* #Copyright
*/
public class ConvertToMap {
String names;
String values;
public String getNames() {
return names;
}
public void setNames(String names) {
this.names = names;
}
public String getValues() {
return values;
}
public void setValues(String values) {
this.values = values;
}
private static String DIGIT_REGEX = "[^0-9]";
private static String LETTER_DIGIT_REGEX = "[a-zA-Z]+";
public static Integer getDigit(String str){
Pattern pattern = Pattern.compile(DIGIT_REGEX);
if(!isLetterDigit(str)){
String[] keySet = pattern.split(str);
if(keySet.length > 0){
return Integer.valueOf(keySet[1]);
}
}
return -1;
}
public static boolean isLetterDigit(String str){
return str.matches(LETTER_DIGIT_REGEX);
}
private static String fetchGroupKey(ConvertToMap convertToMap){
return String.valueOf(getDigit(convertToMap.names));
}
public static void main(String[] args) {
String jsonString = "[{\n" +
" \"names\": \"Car\",\n" +
" \"values\": \"Toyota\"\n" +
" },\n" +
" {\n" +
" \"names\": \"Bike\",\n" +
" \"values\": \"Schwinn\"\n" +
" },\n" +
" {\n" +
" \"names\": \"Scooter\",\n" +
" \"values\": \"Razor\"\n" +
" },\n" +
" {\n" +
" \"names\": \"A0\",\n" +
" \"values\": \"11\"\n" +
" },\n" +
" {\n" +
" \"names\": \"A1\",\n" +
" \"values\": \"12\"\n" +
" },\n" +
" {\n" +
" \"names\": \"A2\",\n" +
" \"values\": \"13\"\n" +
" },\n" +
" {\n" +
" \"names\": \"B0\",\n" +
" \"values\": \"2000\"\n" +
" },\n" +
" {\n" +
" \"names\": \"B1\",\n" +
" \"values\": \"4000\"\n" +
" },\n" +
" {\n" +
" \"names\": \"B2\",\n" +
" \"values\": \"22000\"\n" +
" }\n" +
"]";
List<ConvertToMap> convertToMaps = JacksonUtils.toJavaList(jsonString, ConvertToMap.class);
// Extract a string that does not contain numbers and convert it to a map
Map<String, Object> result = convertToMaps.stream()
.filter(x -> isLetterDigit(x.names))
.collect(Collectors.toMap(ConvertToMap::getNames, ConvertToMap::getValues));
List<Map<String, String>> mapList = new ArrayList<>();
// Group by string numbers containing numbers
Map<String, List<ConvertToMap>> stringListMap = convertToMaps.stream().collect(groupingBy(convertToMap -> fetchGroupKey(convertToMap)));
for (String key : stringListMap.keySet()) {
if(Integer.valueOf(key) >= 0){
mapList.add(stringListMap.get(key)
.stream()
.collect(Collectors.toMap(ConvertToMap::getNames, ConvertToMap::getValues)));
}
}
result.put("Data", mapList);
System.out.println(JacksonUtils.toJSONString(result));
}
}
Assume that your data key name pattern is one non-digit followed by digits.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"[" +
" {" +
" \"names\": \"Car\"," +
" \"values\": \"Toyota\"" +
" }," +
" {" +
" \"names\": \"Bike\"," +
" \"values\": \"Schwinn\"" +
" }," +
" {" +
" \"names\": \"Scooter\"," +
" \"values\": \"Razor\"" +
" }," +
" {" +
" \"names\": \"A0\"," +
" \"values\": \"11\"" +
" }," +
" {" +
" \"names\": \"A1\"," +
" \"values\": \"12\"" +
" }," +
" {" +
" \"names\": \"A2\"," +
" \"values\": \"13\"" +
" }," +
" {" +
" \"names\": \"B0\"," +
" \"values\": \"2000\"" +
" }," +
" {" +
" \"names\": \"B1\"," +
" \"values\": \"4000\"" +
" }," +
" {" +
" \"names\": \"B2\"," +
" \"values\": \"22000\"" +
" }" +
"]");
Transformation
JsonNode node = josson.getNode(
"#collect([names !=~ '\\D\\d+']*" +
" .map(names::values)" +
" ,[names =~ '\\D\\d+']*" +
" .group(names.substr(1), map(names::values))#" +
" .elements" +
" .mergeObjects()" +
" .#toObject('Data')" +
")" +
".flatten(1)" +
".mergeObjects()");
System.out.println(node.toPrettyString());
Output
{
"Car" : "Toyota",
"Bike" : "Schwinn",
"Scooter" : "Razor",
"Data" : [ {
"A0" : "11",
"B0" : "2000"
}, {
"A1" : "12",
"B1" : "4000"
}, {
"A2" : "13",
"B2" : "22000"
} ]
}

How to get nested JSON data within an array using Java?

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]

Json Response to string Array

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.

Elasticsearch: rewrite a query using java native api

I have this query in Elasticsearch that is working perfectly if I run it from the command line:
POST http://localhost:9200/YOUR_INDEX_NAME/_search/
{
"size": 0,
"aggs": {
"autocomplete": {
"terms": {
"field": "autocomplete",
"order": {
"_count": "desc"
},
"include": {
"pattern": "c.*"
}
}
}
},
"query": {
"prefix": {
"autocomplete": {
"value": "c"
}
}
}
}
I have tried to rewrite it in java using the native client:
SearchResponse searchResponse2 = newClient.prepareSearch(INDEX_NAME)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery("{\n" +
" \"size\": 0,\n" +
" \"aggs\": {\n" +
" \"autocomplete\": {\n" +
" \"terms\": {\n" +
" \"field\": \"autocomplete\",\n" +
" \"order\": {\n" +
" \"_count\": \"desc\"\n" +
" },\n" +
" \"include\": {\n" +
" \"pattern\": \"c.*\"\n" +
" }\n" +
" }\n" +
" }\n" +
" },\n" +
" \"query\": {\n" +
" \"prefix\": {\n" +
" \"autocomplete\": {\n" +
" \"value\": \"c\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}").get();
for (SearchHit res : searchResponse2.getHits()){
System.out.println(res.getSourceAsString());
}
Seems, that I'm missing something in this translation process. Thanks in advance
The Java client setQuery() method doesn't take a String with the JSON query, you need to build the query using the QueryBuilders helper methods and build the aggregation your the AggregationBuilders helper methods.
In your case that would go like this:
// build the aggregation
TermsBuilder agg = AggregationBuilders.terms("autocomplete")
.field("autocomplete")
.include("c.*")
.order(Terms.Order.count(false));
// build the query
SearchResponse searchResponse2 = newClient.prepareSearch(INDEX_NAME)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setSize(0)
.setQuery(QueryBuilders.prefixQuery("autocomplete", "c"))
.addAggregation(agg)
.get();

Categories