JSONArray weird results - java

I was trying to get some information from a different class in java using JSONArrays and JSONObjects but for some reason I get very weird results.
My Info.java class I have:
public JSONArray getSpawnedPets() {
JSONArray petsArray = new JSONArray();
JSONObject petO = new JSONObject();
boolean spawned = false;
for (int i = 0; i <= 3; i++) {
spawned = true;
if (spawned) {
petO.put("petID", i);
petO.put("petOwner", "owner"+i);
petO.put("petName", "name");
petO.put("color", "s");
petO.put("particle", "s");
petsArray.add(petO);
}
}
return petsArray;
}
On my Main.java class I have:
public class main {
public static void main(String[] args) {
JSONArray petsArray = new JSONArray();
Info in = new Info();
petsArray = In.getSpawnedPets();
if (petsArray != null) {
for (int i = 0; i < petsArray.size(); i++) {
JSONObject po = (JSONObject) petsArray.get(i);
System.out.println("PetInfo:");
System.out.println(po.get("petID")+":");
System.out.println(""+po.get("petName"));
System.out.println(""+po.get("petOwner"));
}
}
}
}
The results were supposed to be increasing but yet I get this:
PetInfo:
3:
name
owner3
PetInfo:
3:
name
owner3
PetInfo:
3:
name
owner3
PetInfo:
3:
name
owner3
Did I do something wrong? I can't find my problem, the same code but not using classes works, but I have to use classes for it.
Cheers.

Create jsonobject in every iteration otherwise , there is only one JSONObject JSONObject petO = new JSONObject(); which is being updated in every iteration of loop
JSONArray petsArray = new JSONArray();
JSONObject petO;
//boolean spawned = false; // no need of it
for (int i = 0; i <= 3; i++) {
//spawned = true;
//if (spawned) { // no need of it , has no effect, always true
petO = new JSONObject();
// ^^^^^^^^^^^^^^^^^
petO.put("petID", i);
petO.put("petOwner", "owner"+i);
petO.put("petName", "name");
petO.put("color", "s");
petO.put("particle", "s");
petsArray.add(petO);
//}
}
Note : Since spawned is a local variable and will be set to true in first iteration and has no effect in code so there is no need of if

Related

Arraylist not getting repopulated after using notifyDataSetChanged() in java andriod

I am trying to use arraylist.clear and adapter.notifyDataSetChanged() to clear an arraylist the list is cleared successfully but when i try to reload the list again with some data the list is not showing despite the arraylist.size showing the total number of items which is greater than 0. Here is the method to create the initial list
private void getTH(int ID) {
url = "url";
mainAdapterClasses = new ArrayList<>();
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, response -> {
try {
JSONObject jsonObject0 = new JSONObject(response);
String code = jsonObject0.getString("code");;
if (code.matches("200")) {
JSONArray jsonArray = jsonObject1.getJSONArray("items");
if(jsonArray.length() == 0){
txtEmpty.setText(String.format("%s %s", getString(R.string.no), getString(R.string.empty)));
} else {
for (int k = 0; k < jsonArray.length(); k++) {
JSONObject jsonObject = jsonArray.optJSONObject(k);
String na = jsonObject.optString("na", "NA");
String aT = jsonObject.optString("Type", "NA")
MainAdapterClass mainAdapterClass = new MainAdapterClass();
mainAdapterClass.setName(na);
mainAdapterClass.setType(aT);
mainAdapterClasses.add(mainAdapterClass);
}
mainAdapter = new TAdapter(WalletHome.this, mainAdapterClasses);
listView.setAdapter(mainAdapter);
mainAdapter.notifyDataSetChanged();
txtEmpty.setText("Data Is Here"+mainAdapterClasses.size());
}
}
} catch (JSONException e) {
Toast.makeText(this, ""+getString(R.string.unknown_err), Toast.LENGTH_SHORT).show();
}
})
requestQueue.add(stringRequest);
}
and here is the code that is supposes to reload the list
#Override
public void getRadioButtonListener1(int position) {
WClass wClass = stateClassArrayList.get(position);
wId = wClass.getWId();
if(mainAdapter.getCount() > 0){
mainAdapterClasses.clear();
mainAdapter.notifyDataSetChanged();
getTH(id);
}
}
I tried to log the issue here the method is getting the current total of items everytime i run the method the only issue is that the list is not getting populated with the new data once it is initially cleared.
txtEmpty.setText("Data Is Here"+mainAdapterClasses.size());
Any help will be greatly appreciated thanks
At first glance it looks like you are creating and populating the "MainAdapterClass" with the "na" and "aT" variables but not using them anywhere, so you are not really adding items to mainAdapterClasses array.
Second of all, in the for loop you are recreating and setting the adapter each time. I would advise creating and setting the adapter outside of the foor loop once you have your array (mainAdapterClasses) populated with the requested items.
for (int k = 0; k < jsonArray.length(); k++) {
JSONObject jsonObject = jsonArray.optJSONObject(k);
String na = jsonObject.optString("na", "NA");
String aT = jsonObject.optString("Type", "NA")
MainAdapterClass mainAdapterClass = new MainAdapterClass();
mainAdapterClass.setName(na);
mainAdapterClass.setType(aT);
mainAdapterClasses.add(mainAdapterClass);
} //for
mainAdapter = new TAdapter(WalletHome.this, mainAdapterClasses);
listView.setAdapter(mainAdapter);
mainAdapter.notifyDataSetChanged();
txtEmpty.setText("Data Is Here"+mainAdapterClasses.size());
You forgot to add mainAdapterClass to the ArrayList.
for (int k = 0; k < jsonArray.length(); k++) {
JSONObject jsonObject = jsonArray.optJSONObject(k);
String na = jsonObject.optString("na", "NA");
String aT = jsonObject.optString("Type", "NA")
MainAdapterClass mainAdapterClass = new MainAdapterClass();
mainAdapterClass.setName(na);
mainAdapterClass.setType(aT);
mainAdapterClasses.add(mainAdapterClass); // Add this line.
}
Don't setAdapter inside the loop. Just add items and then set the adapter outside the loop.
Also calling notifyDataSetChanged() after setting adapter doesn't make sence.
for (int i = 0; i < jsonArray.length(); i++) {
// ...
}
listview.setAdapter(mainAdapter);

How to parse JSONArray which is in another JSONArray

I am trying to parse a JSONObject.
This JSONObject has a JSONArray in it, and it has another JSONArray inside of JSONArray.
The json form that I am trying to parse is as below.
{
"phone":"01029093199",
"store_id":"1",
"orders":[
{
"menu_id":"4",
"menu_defaultprice":"1500",
"extraorders":[
{
"extra_id":"1",
"extra_price":"0",
"extra_count":"1"
},
{
"extra_id":"38",
"extra_price":"300",
"extra_count":"2"
}
]
},
{
"menu_id":"4",
"menu_defaultprice":"1500",
"extraorders":[
{
"extra_id":"2",
"extra_price":"0",
"extra_count":"1"
},
{
"extra_id":"19",
"extra_price":"500",
"extra_count":"1"
}
]
},
{
"menu_id":"6",
"menu_defaultprice":"2000",
"extraorders":[
{
"extra_id":"6",
"extra_price":"0",
"extra_count":"1"
},
{
"extra_id":"21",
"extra_price":"500",
"extra_count":"1"
},
{
"extra_id":"41",
"extra_price":"300",
"extra_count":"1"
}
]
}
]
}
The code below is what I have tried before.
#RestController
public class OrderApiController {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
#PostMapping("/OrderInsert.do")
public void insertOrder(#RequestBody JSONObject jsonObject) {
JSONParser jsonParser = new JSONParser();
System.out.println(jsonObject);
System.out.println(jsonObject.get("phone")); // phone 가져오기 성공
System.out.println(jsonObject.get("store_id")); // store_id 가져오기 성공
System.out.println("==========JSONArray Parsing start=========");
ArrayList<JSONArray> jsonArrayList = (ArrayList<JSONArray>)jsonObject.get("orders");
for(int i = 0; i < jsonArrayList.size(); i++) {
System.out.println(jsonArrayList.get(i)); // SUCCESS
String temp = jsonArrayList.get(i).toJSONString(); // WHERE ERROR HAPPENS
System.out.println(temp);
// Tried below code to remove "[", "]" from JSONArray, but not working.
// Error message was same as the message shown from line 37.
//String jsonString = temp.substring(1, temp.length()-1);
//System.out.println(jsonString);
// org.json.JSONObject jTemp = new org.json.JSONObject(jsonArrayList.get(i));
// System.out.println(jTemp); --> prints {} (empty JSONObject)
// System.out.println("menu_id : " + jTemp.getInt("menu_id")); // Not Working
}
}
}
The error shown is ..
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.json.simple.JSONArray
Additionally, I am using this json module dependency.
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
I knew that if I print something on console using System.out.println(OBJECT), the OBJECT's toString()
method is called. So I tried to call toString() , and that gave me the ClassCastException exception.
Error is in fact at ArrayList<JSONArray> jsonArrayList = (ArrayList<JSONArray>)jsonObject.get("orders");
Instead of casting JSONArray to ArrayList, you can traverse JSONArray and read its attributes. Your code can be changed something like.
#PostMapping("/OrderInsert.do")
public void insertOrder(#RequestBody JSONObject jsonObject) {
System.out.println(jsonObject);
System.out.println(jsonObject.get("phone")); // phone 가져오기 성공
System.out.println(jsonObject.get("store_id")); // store_id 가져오기 성공
System.out.println("==========JSONArray Parsing start=========");
JSONArray orders = jsonObject.getJSONArray("orders");
for(int i = 0; i < orders.length(); i++) {
System.out.println(orders.get(i)); // SUCCESS
String temp = orders.get(i).toString();
System.out.println(temp);
// Travserse further json
JSONObject order = orders.getJSONObject(i);
System.out.println(order.get("menu_defaultprice"));
System.out.println(order.get("menu_id"));
JSONArray extraorders = order.getJSONArray("extraorders");
for(int j = 0; j < extraorders.length(); j++) {
JSONObject extraOrder = extraorders.getJSONObject(j);
System.out.println(extraOrder.get("extra_id"));
System.out.println(extraOrder.get("extra_price"));
System.out.println(extraOrder.get("extra_count"));
}
}
}
You are incorrectly fetching the orders. It should be stored in JSONArray, and NOT ArrayList
Replace:
ArrayList<JSONArray> jsonArrayList = (ArrayList<JSONArray>)jsonObject.get("orders");
With:
JSONArray jsonArrayList = jsonObject.getJSONArray("orders");
Now, you can iterate JSONArray like this
for(int i = 0; i < jsonArrayList.length(); i++) {
System.out.println(jsonArrayList.get(i)); // SUCCESS
String temp = jsonArrayList.get(i).toJSONString();
System.out.println(temp);
}

How to contruct nested JSON using retrofit2

I am trying to construct a bit complex nested JSON for a POST request in my Android application, I am using Retrofit2 and GSON converter.
After constructing, I used GSON to print it out in order to be sure of what will be sent to the API endpoint. Below is the output I got
{
"agent_id":"testy",
"answer":[
{
"answer":"Yes",
"question_id":"1"
},
{
"answer":"Yes",
"question_id":"5"
},
{
"answer":"No",
"question_id":"6"
},
{
"answer":"No",
"question_id":"7"
},
{
"sub_question":[
{"sub_question_id":"2"},
{"sub_question_id":"2"},
{"sub_question_id":"2"},
{
"sub_answer":[
{"coord":"6.4378537,3.4289744000000155","text":""},
{"coord":"6.4378537,3.4289744000000155","text":""},
{"coord":"6.4378537,3.4289744000000155","text":""}
]
}
]
}
],
"street_id":3,
"token":"afadfadfadfdfHFGD_JSDHD"
}
However, the actual format I need is as seen below
{
"agent_id":"testy",
"answer":[
{
"answer":"Yes",
"question_id":"1",
"sub_question":[
{
"sub_question_id":"2",
"sub_answer":[
{"coord":"6.4378537,3.4289744000000155","text":""}
]
}
]
},
{
"answer":"No",
"question_id":"5",
"sub_question":[
{
"sub_question_id":"2",
"sub_answer":[
{"coord":"6.4378537,3.4289744000000155","text":""}
]
}
]
},
{
"answer":"Yes",
"question_id":"6",
"sub_question":[
{
"sub_question_id":"2",
"sub_answer":[
{"coord":"6.4378537,3.4289744000000155","text":""}
]
}
]
},
{
"answer":"No",
"question_id":"7",
"sub_question":[
{
"sub_question_id":"2",
"sub_answer":[
{"coord":"6.4378537,3.4289744000000155","text":""}
]
}
]
}
],
"street_id":3,
"token":"asdfasdfasdf3453adfafdaADN"
}
The code that does the construction is below
private void submitAnswers() {
List<Answer> answerList = new ArrayList<>();
List<SubQuestion> subQuestionList = new ArrayList<>();
List<SubAnswer> subQuestionAnswerList = new ArrayList<>();
//Adding QuestionID and QuestionAnswer to the Answer array
for (int k = 0; k < questSize.size(); k++) {
Answer answer1 = new Answer();
answer1.setQuestion_id(mainQuestAnsID.get(k));
answer1.setAnswer(mainQuestAns.get(k));
answerList.add(answer1);
}
for (int j = 0; j < subQuestID.size(); j++) {
SubQuestion subQuest = new SubQuestion();
subQuest.setSub_question_id(subQuestID.get(j));
subQuestionList.add(subQuest);
}
for (int h = 0; h < subQuestAns.size(); h++) {
SubAnswer subQuestionAnswer = new SubAnswer();
subQuestionAnswer.setText(subQuestAns.get(h));
subQuestionAnswer.setCoord("6.4378537,3.4289744000000155");
subQuestionAnswerList.add(subQuestionAnswer);
}
Answer answer = new Answer();
answer.setSub_question(subQuestionList);
answerList.add(answer);
SubQuestion subQuest = new SubQuestion();
subQuest.setSub_answer(subQuestionAnswerList);
subQuestionList.add(subQuest);
AnswerRequest answerRequest = new AnswerRequest();
answerRequest.setAgent_id(agentID);
answerRequest.setToken(token);
answerRequest.setStreet_id(streetID);
answerRequest.setAnswer(answerList);
//Gson for printing out the JSON
Gson gson = new Gson();
Type type = new TypeToken<AnswerRequest>() {
}.getType();
String json = gson.toJson(answerRequest, type);
System.out.println(json);
}
Can anyone tell what is wrong that makes me not to get the desired output?
I guess the main reason is that you are building your lists separately, while you should do it once for every answer.
For what I understand from your expected output, you have:
1 main object that has some parameters and a list of answer
each answer has some parameters and a list of subquestion
each subquestion has some parameters and a list of subanswers
So you should build your object in the same way. E.g. for each new answer, construct its list of subquestion, for each subquestion construct its list of subanswer
Code speaking it would be something like this:
for (int k = 0; k < questSize.size(); k++) {
Answer answer1 = new Answer();
answer1.setQuestion_id(mainQuestAnsID.get(k));
answer1.setAnswer(mainQuestAns.get(k));
// now construct the subquestion list of that new answer
List<SubQuestion> subQuestions = new ArrayList<>();
for (int j = 0; j < subQuestID.size(); j++) { // change the loop to get only what you need for the current answer
SubQuestion subQuest = new SubQuestion();
// add all the subquestions related to the answer here
...
// Construct the subanswer of that new subquestion
List<SubAnswer> subAnswers = new ArrayList<>();
for (int h = 0; h < subQuestAns.size(); h++) { // adapt the loop to get the subanswers related to the current subquestion
SubAnswer subQuestionAnswer = new SubAnswer();
// get the infos needed for this subanswer
...
// add the new subanswer to the list
subAnswers.add(subQuestionAnswer);
}
// add the subanswer list to the subquestion
subQuest.setSub_answer(
// add the subquestion to the list
subQuestions.add(subQuest);
}
// then add the list to the answer
answer1.setSub_question(subQuestions);
// finally add the answer to the list
answerList.add(answer1);
}
// now you can create the AnswerRequest object like before
And you should have a result that looks more like what you need now :)

Get JSON String by iterating over array inside an object

Im working on an app where Im parsing JSON file and get the strings from it, but there is one String I have no idea why cant I get it into my activity.
the String is Object > Array > String
I have 2 activities and 1 model.
MainActivity: where Im parsing the JSON.
DetailActivity: where I need the String.
PostModel: a model where I have all setter and getter.
JSON:
{
"status":"ok",
"count":10,
"count_total":184,
"pages":19,
"posts":[
{ },
{
"id":2413,
,
"categories":[
{
"id":100,
"slug":"logging",
"title":"logging",
"description":"",
"parent":0,
"post_count":1
}
],
"comments":[
{
"id":3564,
"content":"<p>\u47 <\/p>\n",
"parent":0
}
],
"comment_count":1,
"thumbnail":"http:\/\/www.5.com\/wtent\g",
"custom_fields":{
"dsq_thread_id":[
"2365140"
],
"videoID":[
"--ffwf92jvDFy"
]
},
"thumbnail_images":{
"full":{
"url":"http:\/\/www.5.com\/jpg",
"width":727,
"height":454
},
"thumbnail":{
"url":"http:\/\/www.5.com\/wp-con50.jpg",
"width":150,
"height":150
}
}
}
]
}
PostModel:
private List<VidCast> videoIDList;
private String videoID;
public String getVideoID() {
return videoID;
}
public void setVideoID(String videoID) {
this.videoID = videoID;
}
public List<VidCast> getvideoIDList() { return videoIDList; }
public void setvideoIDList(List<VidCast> videoIDList) {
this.videoIDList = videoIDList;
}
public static class VidCast {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
MainActivity:
List<PostModel.VidCast> vidCasts = JsonPath.parse(URL_TO_HIT).read("$.posts.[*].custom_fields.[*].videoID[*]");
vidCasts = new ArrayList<>();
for (int s = 0 ; s < finalObject.getJSONArray("custom_fields").length() ; s++){
PostModel.VidCast vidCast = new PostModel.VidCast();
vidCast.setName(videoID);
vidCasts.add(vidCast);
}
postModel.setvideoIDList(vidCasts);
// adding the final object in the list
postModelList.add(postModel);
}
return postModelList;
}
}
DetailActivity:
StringBuffer stringBuffer = new StringBuffer();
for(PostModel.CategoryCast categoryCast : postModel.getCategoryCastList()){
stringBuffer.append(categoryCast.getName() + ", ");
}
StringBuffer videoStringBuffer = new StringBuffer();
for(PostModel.VidCast videoIDList : postModel.getvideoIDList()) {
videoStringBuffer.append(videoStringBuffer.toString());
}
At the last file is where I need to get the <> String. I spent a lot of time I just cant figure it out how I can iterate over array inside an object.
Thanks in advance!
__________update________
I managed to parse it that way :
JSONObject customFields = finalObject.getJSONObject("custom_fields");
JSONArray vidCastsJson = customFields.getJSONArray("videoID");
List<PostModel.VidCast> videoIds = new ArrayList<>();
for (int s = 0 ; s < vidCastsJson.length() ; s++){
PostModel.VidCast vidCast = new PostModel.VidCast();
vidCast.setName(vidCastsJson.optString(s));
videoIds.add(vidCast);
String videoID = String.valueOf(vidCastsJson);
vidCast.setName(videoID);
and I use Stringbuffer at DetailActivityStringBuffer
videoStringBuffer = new StringBuffer();
for(PostModel.VidCast vidCast : postModel.getvideoIDList()) {
videoStringBuffer.append(vidCast.getName());
String videoID = vidCast.toString();
}
But now I'm getting the videoID with the array brackets like that ["F3lyzrt"] I want it as a string to be only F3lyzrt, so I can pass it to my youtube player. Any advice will be appropriated.
Thanks,
It would look something like this:
JSONObject root = // however you get your root JSON object
JSONArray posts = root.optJSONArray("posts");
for(int i=0; i < posts.length(); i++){
JSONObject post = posts.optJSONObject(i);
int id = post.optInt("id");
JSONArray categories = post.optJSONArray("categories");
// etc.
}
Though you might want to consider using GSON or Jackson. With those libraries you can define a model to represent the data (jsonschema2pojo.org can help with that) and then it does all the parsing for you.
EDIT
You're not even trying to get the video id. Here's your code:
for (int s = 0; s < finalObject.getJSONArray("videoID").length(); s++){
{
postModel.setVideoID(videoID);
postModelList.add(postModel);
}
You see how you're not retrieving the contents of the json array?
JSONArray videoIds = finalObject.getJSONArray("videoID");
for (int s = 0; s < videoIds.length(); s++){
String videoID = videoIds.optString(s);
postModel.setVideoID(videoID);
postModelList.add(postModel);
}

What is the best way to loop over an array in JsonValue in libgdx?

I am porting an Android-only Game to libgdx. The world and level info is stored in a json file.
I used to do access the array with getJSONArray(id) like this:
public static WorldVO create(JSONObject worldObject) {
WorldVO worldVO = new WorldVO();
worldVO.id = worldObject.getInt("id");
worldVO.unlock = worldObject.getInt("stars_to_unlock");
worldObject.getChild("levels");
JSONArray levelJsonArray = worldObject.getJSONArray("levels");
int len = levelJsonArray.length();
worldVO.levelVOs = new LevelVO[len];
for (int i = 0; i < len; i++) {
worldVO.levelVOs[i] = LevelVO.create(levelJsonArray.getJSONObject(i));
}
...
which worked fine but I cannot find the correct way to loop through the "levels" child of the "worldObect" Json in libgdx when i use JsonValue instead of JSONObject.
Accessing the integer fields is not a problem but JsonValue does not have a getJSONArray. Any idea what to use? Thanks!
Based on this : http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/JsonValue.html
Try this :
public static WorldVO create(JsonValue worldObject)
{
WorldVO worldVO = new WorldVO();
worldVO.id = worldObject.getInt("id");
worldVO.unlock = worldObject.getInt("stars_to_unlock");
JsonValue levels = worldObject.get("levels");
int len = levels.size;
worldVO.levelVOs = new LevelVO[len];
for (int i = 0; i < len; i++)
{
worldVO.levelVOs[i] = LevelVO.create(levels.get(i));
}

Categories