How to call methods (maybe recursive) itself JAVA - java

Hello I am new in Java and I have a question.
I am using a package to parse JSON Markups but the following problem is this:
{
"example": {
"subThing": "value"
},
"anotherThing" : 0
...
}
if I call MyClass.getString("example").getString("subThing"); then I am getting the value of subThing.
I want to call these getString() so often as possible ina for loop programmatically with index variable. But I don't know how to do.
for(int i = 0; i > getCurrentState(); i++) {
//Here I want to call getString();
//I want in round loop to call getString();
//In second round loop to call getString().getString();
}
Sorry I just started using java 1 week ago.
edit:
I mean how to call get() and/or getString() programmatically in for loop?

I'm not sure if I understand you correctly, but you may use the following technique here:
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class App
{
public static void main( String[] args ) throws JSONException {
JSONObject newObj = new JSONObject("{" +
"\"data\": [\n" +
" {\n" +
"\"id\": 1,\n" +
" \"userId\": 1,\n" +
" \"name\": \"ABC\",\n" +
" \"modified\": \"2014-12-04\",\n" +
" \"created\": \"2014-12-04\",\n" +
" \"items\": [\n" +
" {\n" +
" \"email\": \"abc#gmail.com\",\n" +
" \"links\": [\n" +
" {\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"\n" +
"}");
JSONArray items = newObj.getJSONArray("data");
for (int it = 0; it < items.length(); it++) {
JSONObject contactItem = items.getJSONObject(it);
String userName = contactItem.getString("name");
JSONArray item = contactItem.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
String email = item.getJSONObject(i).getString("email");
System.out.println(email);
}
System.out.println("Name----------" + userName);
}
}
}
or even better and simpler is to use JsonPath
For your json is would be smth like this
String substring = JsonPath.parse(json).read("$.example.subThing", String.class);
String anotherstring = JsonPath.parse(json).read("$.anotherThing", String.class);

Related

Response result from RapidAPI gives Relaxed JSON

I got this response from RapidAPI, As you see in the picture the name indicated by the red vector
is without quotes. I searched for that and I found that is called Relaxed JSON, but I didn't find how to parse this type using Java language.
This works for me
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
String text = "{\n" +
" \"array\": [\n" +
" {\n" +
" 0: {\n" +
" \"id\": 1\n" +
" }\n" +
" },\n" +
" {\n" +
" 1: {\n" +
" \"id\": 2\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
JsonParser parser = new JsonFactory()
.createParser(text)
.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
JsonNode root = new ObjectMapper().readTree(parser);
System.out.println(root);
Result
{"array":[{"0":{"id":1}},{"1":{"id":2}}]}
It's nothing but that 0 is indicating the first value inside the quotes array. Quotes is an array with the 7 objects values. You can access them or get each value from an array using the org.json library.
import org.json.*;
JSONArray arr = obj.getJSONArray("quotes");
for (int i = 0; i < arr.length(); i++)
{
String exchange = arr.getJSONObject(i).getString("exchange");
String shortname = arr.getJSONObject(i).getString("shortname");
.
.
.
// And so on...
}

Facing issue in extracting value from nested jsonArray

I know a similar question has been posted, however, the answer didn't work for me.
I am new to this RestAssured.I want to get the 'uuid' value if categories equals to 'FUNGI' and feature->features conatains 'VRA'.This is my sample json:
[{
"uuid":"e223d29b-499b-b58b-995e-654bef1aab03",
"categories":[
{
"uuid":"89d1c022-4453-5f6b-883c-46730d429b2a",
"name":"FERTI"
}
],
"minRateSi":0.0
},
{
"uuid":"93015a1b-76ac-2ca3-2bbc-5ae5480962c2",
"categories":[
{
"uuid":"61c951b1-3e47-f0a0-80d8-3d43efa339fb",
"name":"FUNGI"
}
],
"minRateSi":0.0,
"maxRateSi":7.5E-8,
"features":[
{
"id":"9b4ee6b2-ae2d-6c9a-af77-08a4b749031f",
"vraMinRate":2.0E-8,
"features":[
"VRA"
]
},
{
"id":"ec0d0f52-dd71-ebb9-0a39-831768fe4490",
"vraMinRateSi":3.0E-8,
"features":[
"VRA"
]
}
]
},
{
"uuid":"38290452-4937-4f33-c54d-7f502b84ed99",
"categories":[
{
"uuid":"2c9d8cc0-01bc-899d-6782-cf412e90fd78",
"name":"FUNGI"
}
],
"maxRateSi":1.0E-7,
"features":[
{
"id":"9b4ee6b2-ae2d-6c9a-af77-08a4b749031f",
"vraMinRateSi":6.5E-8
},
{
"cropUuid":"ec0d0f52-dd71-ebb9-0a39-831768fe4490",
"vraMinRateSi":5.0E-8
}
]}]
Woo , okay your case was pretty hard to break down, but as far as you know how to use JSONArray and JSONObject classes you will be fine.
First of all let me mention how you should approach this kind of scenarios.
I prefer using an online JSON Formatter like this one simply paste your JSON payload and you will be able to tell whether to use JSONObject or JSONArray.
Please take a note here, and check out how to parse json payloads
This code will work for you, although you need to find out the logic behind it and implement JSON parsing accordingly in your future cases.
//declaring your payload
String myJsonPayload = "[{\r\n" + " \"uuid\":\"e223d29b-499b-b58b-995e-654bef1aab03\",\r\n" +
" \"categories\":[\r\n" + " {\r\n" +
" \"uuid\":\"89d1c022-4453-5f6b-883c-46730d429b2a\",\r\n" +
" \"name\":\"FERTI\"\r\n" + " }\r\n" + " ],\r\n" +
" \"minRateSi\":0.0\r\n" + " },\r\n" + " {\r\n" +
" \"uuid\":\"93015a1b-76ac-2ca3-2bbc-5ae5480962c2\",\r\n" + " \"categories\":[\r\n" +
" {\r\n" + " \"uuid\":\"61c951b1-3e47-f0a0-80d8-3d43efa339fb\",\r\n" +
" \"name\":\"FUNGI\"\r\n" + " }\r\n" + " ],\r\n" +
" \"minRateSi\":0.0,\r\n" + " \"maxRateSi\":7.5E-8,\r\n" + " \"features\":[\r\n" +
" {\r\n" + " \"id\":\"9b4ee6b2-ae2d-6c9a-af77-08a4b749031f\",\r\n" +
" \"vraMinRate\":2.0E-8,\r\n" + " \"features\":[\r\n" +
" \"VRA\"\r\n" + " ]\r\n" + " },\r\n" + " {\r\n" +
" \"id\":\"ec0d0f52-dd71-ebb9-0a39-831768fe4490\",\r\n" +
" \"vraMinRateSi\":3.0E-8,\r\n" + " \"features\":[\r\n" +
" \"VRA\"\r\n" + " ]\r\n" + " }\r\n" + " ]\r\n" + " },\r\n" +
" {\r\n" + " \"uuid\":\"38290452-4937-4f33-c54d-7f502b84ed99\",\r\n" +
" \"categories\":[\r\n" + " {\r\n" +
" \"uuid\":\"2c9d8cc0-01bc-899d-6782-cf412e90fd78\",\r\n" +
" \"name\":\"FUNGI\"\r\n" + " }\r\n" + " ],\r\n" +
" \"maxRateSi\":1.0E-7,\r\n" + " \"features\":[\r\n" + " {\r\n" +
" \"id\":\"9b4ee6b2-ae2d-6c9a-af77-08a4b749031f\",\r\n" +
" \"vraMinRateSi\":6.5E-8\r\n" + " },\r\n" + " {\r\n" +
" \"cropUuid\":\"ec0d0f52-dd71-ebb9-0a39-831768fe4490\",\r\n" +
" \"vraMinRateSi\":5.0E-8\r\n" + " }\r\n" + " ]}]";
JSONArray json = new JSONArray(myJsonPayload);
System.out.println(json);
for (int i = 0; i < json.length(); i++) {
JSONObject object = (JSONObject) json.get(i);
// System.out.println(object); // you have each JSONObject { } contained in the
// Outer JSONArray [ ]
//Getting both uuid's since you didn't answer which one.
String uuid = object.getString("uuid");
System.out.println("\n\n Next Object - Outer UUID: " + uuid);
JSONArray categories = object.getJSONArray("categories");
System.out.println(categories);
if (((JSONObject) categories.get(0)).getString("name").equalsIgnoreCase("fungi")) {
System.out.println("\nFUNGI found!:\n");
//Getting the inner UUID
String uuidOfFungi = ((JSONObject) categories.get(0)).getString("uuid");
System.out.println("Inner UUID: " + uuidOfFungi);
} else {
System.out.println("\nFUNGI NOT FOUND (ABORTING):\n");
}
// Getting Features:
try {
JSONArray featuresObject = object.getJSONArray("features");
for (int index = 0; index < featuresObject.length(); index++) {
try {
JSONObject features = featuresObject.getJSONObject(index);
//Getting VRA
String vraFeatues = features.getJSONArray("features").getString(0);
} catch (JSONException e) {
System.out.println("No inner JSONArray in features JSONObject");
}
}
} catch (JSONException e) {
System.out.println("JSON OBJECT " + i + " HAS NO FEATURES ARRAY");
}
}
Depending again on your use-case it's up to you how you will get the JSON payload into your program.
Getting it from remote URL using Java
Passing it as an argument on java -jar execution time , which i don't really recommend
Either case, modifications need to be done in order to initialize myJsonPayload accordingly.
Hope it helped!

Traversing through dynamic JSON to read properties of every child node

I have some JSON which is subject to change but one constant is it will always contain multiple objects with two properties; text and answerText. An example JSON would be
{
"food": {
"eggTolerance": {
"answerText": "None",
"text": "What is your egg tolerance?"
},
"lactoseTolerance": null
},
"cookingExperience": {
"experienceInLastFiveYears": {
"answerText": "Yes",
"text": "Was this experience within the last 5 years?"
},
"numberOfPies": {
"answerText": "More than 50",
"text": "How many pies have you baked?"
},
"significantPies": {
"answerText": "More than 50",
"text": "How many of these pies per quarter were at tasty?"
},
"spanOfExperience": {
"answerText": "Yes",
"text": "Do you have at least 12 months' experience baking pies?"
}
},
"cocktails": {
"manhattans": {
"answerText": "The kiss of death",
"text": "What have I done to deserve this flat, flavourless Manhattan?"
},
"Gin Martini": null
},
"waitressing": null
}
This can be changed by making it deeper or wider. For example the lactoseTolerance could have another object added to it or another object could be added to the root object.
How can I traverse this object to visit every object to get the properties of the deepest object?
I have seen this example but this just gives me the first level. In this instance I know I can then iterate the children of those objects but if the hierarchy changes the implementation is ruined.
I have used GSON lib:
Please try below code:
pom.xml
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Then I have created QA class that have your fixed two properties; text and answerText
import com.google.gson.annotations.SerializedName;
public class QA {
#SerializedName("answerText")
private String answerText;
#SerializedName("text")
private String text;
public QA(String answerText, String text) {
this.answerText = answerText;
this.text = text;
}
#Override
public String toString() {
return "QA{" +
"answerText='" + answerText + '\'' +
", text='" + text + '\'' +
'}';
}
public String getAnswerText() {
return answerText;
}
public void setAnswerText(String answerText) {
this.answerText = answerText;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Now in driver code:
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.Map;
public class Main {
public static void main(String[] args) {
System.out.println("running!!");
InputStream inputStream = Main.class.getResourceAsStream("json.json");
String json = "{\n" +
" \"food\": {\n" +
" \"eggTolerance\": {\n" +
" \"answerText\": \"None\",\n" +
" \"text\": \"What is your egg tolerance?\"\n" +
" },\n" +
" \"lactoseTolerance\": null\n" +
" },\n" +
" \"cookingExperience\": {\n" +
" \"experienceInLastFiveYears\": {\n" +
" \"answerText\": \"Yes\",\n" +
" \"text\": \"Was this experience within the last 5 years?\"\n" +
" },\n" +
" \"numberOfPies\": {\n" +
" \"answerText\": \"More than 50\",\n" +
" \"text\": \"How many pies have you baked?\"\n" +
" },\n" +
" \"significantPies\": {\n" +
" \"answerText\": \"More than 50\",\n" +
" \"text\": \"How many of these pies per quarter were at tasty?\"\n" +
" },\n" +
" \"spanOfExperience\": {\n" +
" \"answerText\": \"Yes\",\n" +
" \"text\": \"Do you have at least 12 months' experience baking pies?\"\n" +
" }\n" +
" },\n" +
" \"cocktails\": {\n" +
" \"manhattans\": {\n" +
" \"answerText\": \"The kiss of death\",\n" +
" \"text\": \"What have I done to deserve this flat, flavourless Manhattan?\"\n" +
" },\n" +
" \"Gin Martini\": null\n" +
" },\n" +
" \"waitressing\": null\n" +
"}";
final Gson gson = new Gson();
Type type = new TypeToken<Map<String, Map<String, QA>>>(){}.getType();
Map<String, Map<String, QA>> myMap = gson.fromJson(json, type);
System.out.println("Data:"+ myMap.get("food").get("eggTolerance").getAnswerText());
}
}

Json Parsing in Java(key is not constant)

Below is my JSON:
{
"-5": [
"15:D1_CHANNEL_ID_SK",
"23:D1_CALL_BEGIN_DATE",
"87:D1_CELL_ID"
],
"-4": [
"31:I_RECHARGE_AMOUNT",
"59:I_INBUNDLED_UNIT",
"60:I_DAY_NIGHT_FLAG",
"53:PD_UPSELL_PACK_ID",
"146:AON"
]
}
In the above Json, the key is also a variable (it is not constant). Because of that I'm not able to parse the json using mapper.readValue().
Im assuming that by mapper.readValue(), you're trying to read a string value into a map like structure (can be a POJO or a HashMap) with the help of an ObjectMapper.
The following code reads from the string and converts it into a Map<String,Object>.
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
String data = "{\n" + " \"-5\": [\n" + " \"15:D1_CHANNEL_ID_SK\",\n" + " \"23:D1_CALL_BEGIN_DATE\",\n" + " \"87:D1_CELL_ID\"\n" + " ],\n" + " \"-4\": [\n" + " \"31:I_RECHARGE_AMOUNT\",\n" + " \"59:I_INBUNDLED_UNIT\",\n" + " \"60:I_DAY_NIGHT_FLAG\",\n" + " \"53:PD_UPSELL_PACK_ID\",\n" + " \"146:AON\"\n" + " ]\n" + "}";
final Map<String, Object> response = objectMapper
.readValue(data, objectMapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class));
}
Of-course, the value type in the map can be an object too. In that case, the code might look like this
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
String data = "{\n" + " \"-5\": [\n" + " \"15:D1_CHANNEL_ID_SK\",\n" + " \"23:D1_CALL_BEGIN_DATE\",\n" + " \"87:D1_CELL_ID\"\n" + " ],\n" + " \"-4\": [\n" + " \"31:I_RECHARGE_AMOUNT\",\n" + " \"59:I_INBUNDLED_UNIT\",\n" + " \"60:I_DAY_NIGHT_FLAG\",\n" + " \"53:PD_UPSELL_PACK_ID\",\n" + " \"146:AON\"\n" + " ]\n" + "}";
final Map<String, Your Class Name> response = objectMapper
.readValue(data, objectMapper.getTypeFactory().constructMapType(Map.class, String.class, <Your Class Name>.class));
}
It is also possible to convert the value type to another container based type (like a List), which I leave for your exploration.

JSON String to POJO, using GSON, clarification needed

I have a JSON file, as String:
String compString = "{\n" +
" \"Component\": {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n" +
" }";
I have a bean representing it (correct if incorrectly)
public class Component {
String name;
String environment;
List<String> hosts = new ArrayList<String>();
List<String> directories = new ArrayList<String>();
// standard getters and setters
}
I am trying to feed this String to this class by:
Gson gson = new Gson();
Component component = gson.fromJson(compString, Component.class);
System.out.println(component.getName());
Above does not work. (I am getting null back, as if Component's name value is never set)
What am i missing please?
In fact, you have to remove the enclosing class from Json.
Indeed, JSON begins with the content of the enclosing class.
So your JSON would be:
String compString = "{\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n";
String compString =
" {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]}" ;
I think you should read more about json, I have removed something in your json string and then success.

Categories