Reading a JsonFile to an ArrayList - java

I have an assingment to create something on the lines of a quiz. The teacher gave us all the interfaces for the Questions and the Test and even the "graphic layer" to display the quiz.
I created two classes for the Test and Question interfaces. The test class has a listArray of Questions objects along with other atributes. The Question class has the atributes you can see in the JSON File(title,score,mark,etc...).
To read the Json file i created the method "loadfromJsonFile", and it prints the file perfectly but i cant figure out how to associate each question object from the file to the arrayList.
Json File:
[
{
"type": "MultipleChoice",
"question": {
"title": "Question 1",
"score": 4,
"mark": 5,
"question_description": "The ability of an object to take on many forms is:",
"options": [
"Polymorphism",
"Encapsulation",
"Design Patter",
"Does not Exist"
],
"correct_answer": "Polymorphism"
}
},
{
"type": "MultipleChoice",
"question": {
"title": "Question 2",
"score": 4,
"mark": 5,
"question_description": "The bundling of data with the methods that operate on that data is:",
"options": [
"Polymorphism",
"Encapsulation",
"Design Patter",
"Does not Exist"
],
"correct_answer": "Encapsulation"
}
},
{
"type": "YesNo",
"question": {
"title": "Question 3",
"score": 4,
"mark": 5,
"question_description": "Object Oriented Programming is exclusive to the JAVA programming language",
"correct_answer": "no"
}
},
{
"type": "Numeric",
"question": {
"title": "Question 4",
"score": 4,
"mark": 5,
"question_description": "How many programming languages are taught in Paradigmas de Programação?",
"correct_answer": "1"
}
}]
Code for reading the Json File:
public boolean loadFromJSONFile(String s) throws TestException {
String path = "teste_A.json";
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(path));
JsonStreamParser p = new JsonStreamParser(reader);
JsonArray arr = (JsonArray) p.next();
for(int i=0;i<arr.size();i++){
System.out.println("--------------------------------------Question"+i+"--------------------------------------------");
JsonElement arrayElement = arr.get(i);
JsonObject obj = arrayElement.getAsJsonObject();
String type=obj.get("type").getAsString();
System.out.println("Type: " + type);
JsonObject list =obj.get("question").getAsJsonObject();
String title=list.get("title").getAsString();
System.out.println("Title: " + title);
int score=list.get("score").getAsInt();
System.out.println("Score: " + score);
int mark=list.get("mark").getAsInt();
System.out.println("Mark: " + mark);
String Description=list.get("question_description").getAsString();
System.out.println("Description: " + Description);
JsonArray opt = list.getAsJsonArray("options");
if(opt!=null){
System.out.println("Options: \n");
for (int j = 0; j < opt.size(); j++) {
JsonPrimitive value = opt.get(j).getAsJsonPrimitive();
System.out.print(" Option"+ (j+1) +": "+ value.getAsString()+ " \n");
}
System.out.println("\n");
}
String CorrectAnswer = list.get("correct_answer").getAsString();
System.out.println("Correct: " + CorrectAnswer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
reader.close();
}catch (IOException ex){
ex.printStackTrace();
}
}
return false;
}

Here is my understanding: you can read the json file and parse the contents just fine, but the issue is how to pass the results back to the caller without returning the parameter itself. From the code snippets, the line
this.current_question = this.test.getQuestion(this.question_number);
seems like where this ArrayList will be queried in the program.
From this, I am imagining a couple of possibilites:
1) There is a setQuestion(<params>) method that you could call in the teacher's provided code.
2) There is a variable such as this.test or this.questions that you should be setting.
In either case, you would add each question inside your for loop. For example,
for(int i=0;i<arr.size();i++){
System.out.println("--------------------------------------Question"+i+"--------------------------------------------");
JsonElement arrayElement = arr.get(i);
JsonObject obj = arrayElement.getAsJsonObject();
//add obj via variable assignment
this.test.Add(obj);
//or, add obj via set method
this.test.setQuestion(i, obj); //or whatever parameters are needed :)
EDIT:
Because your Question class extends IQuestion, you can cast an instance of the Question class to IQuestion. Plus, the Question class is using a Gson library to deserialize for you, which means you saved yourself some legwork. (yay!)
for(int i=0;i<arr.size();i++){
//get the whole json array element
JsonElement arrayElement = arr.get(i);
//...
//get question object
JsonObject list = obj.get("question").getAsJsonObject();
//cast to IQuestion using the Question class Gson deserializer
IQuestion q = new Gson().fromJson(list, Question.class);
//And, add using built in method
this.test.setQuestion(q);
This website has some examples of Gson deserialization, one of which I used up above.
EDIT:
After adding a constructor to the Question class, the code to add a question of specific types will need type casting.
for(int i=0;i<arr.size();i++){
//get the whole json array element
JsonElement arrayElement = arr.get(i);
//...
//get question object
JsonObject list = obj.get("question").getAsJsonObject();
//cast question to correct interface based on question type
if (type=="Multiple Choice") {
IQuestionMultipleChoice questionMP = (IQuestionMultipleChoice) new Question(<params>);
this.test.setQuestion(questionMP);
} else if(type=="Yes/No") {
//...

Related

Cucumber:Assert values irrespective of Index

I am working on updating functional test suites using Cucumber feature file.The issue my output is an array which is not sorted.Index of the object may change.
Array:
[{
"id": "12",
"name": "Something"
},
{
"id": "13",
"name": "Another Something"
}
]
Here I wanna assert name when Id=13 only.Any help would be appreciated.
The Json is list of objects within an Array so you need parse them and validate the each Object. You can do like below,
Code:
JSONArray jsonArray = new JSONArray(JsonAsString);
JSONObject jsonObject;
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject = new JSONObject(jsonArray.get(i).toString());
if (jsonObject.get("id").toString().equalsIgnoreCase("13")) {
System.out.println("Name: " + jsonObject.get("name"));
//do your thing...
}
}
Output:
Name: Another Something

Access only the First Object from a JSON Array

This is my json from the code below:
"ict":[
{
"module1":{
"1":[
"OS",
"Operating system"
],
"2":[
"CA",
"Computer Application"
],
"3":[
"CM",
"Computational Mathematics"
],
"4":[
"CA",
"Computer Application"
],
"5":[
"Programming",
"Structured Programming"
]
},
I want to access this part
"1":["OS","Operating system"]
but get the string "OS" without fetching the whole string.
When I run my java code which is this:
private void addItemsFromJSON() {
try {
JSONObject jsonObject = new JSONObject(readJSONDataFromFile());
JSONArray coursea = jsonObject.getJSONArray("ict");
for (int i = 0; i < coursea.length(); i++) {
JSONObject cc = coursea.getJSONObject(i);
JSONObject contact = cc.getJSONObject("module1");
courses.add(new course(contact.getString("1"),"",String.valueOf(content.get(ran.nextInt(content.size())))));
}
} catch (JSONException | IOException e) {
Log.d(TAG, "addItemsFromJSON: 777", e);
}
}
The output that I get is ["OS", "Operating system"]
How can I retrieve only the first object from a json key array with multiple values?
The data at "1" refers to another JSONArray, so to get the first item in the array you would do something like this:
JSONArray array = contact.getJSONArray("1");
array.getString(0);
In JSON objects are denoted using {} and arrays with []. If you're trying to access a specific value in your JSON object then it's really just a case of following the path to it, through the arrays and objects.

Java - Getting a varying number of json variables

I am building a tool using java, that accesses an API.
I'm trying to let the user decide, which parameters to use (via checkboxes for instance).
So the user would decide to take one of let's say 5 parameters:
p1
p2
p3
p4
p5
and then I would make a call to the API using those parameters and receive a Json String as a response.
So that Json String can be either
{"data":[{"p1":"value1", "p2":"value2", "p3":"value3", "p4":"value4", "p5":"value5"}]}
{"data":[{"p1":"value1", "p2":"value2", "p3":"value3", "p4":"value4"}]}
{"data":[{"p1":"value1", "p2":"value2", "p3":"value3"}]}
{"data":[{"p1":"value1", "p2":"value2"}]}
or
{"data":[{"p1":"value1"}]}
I'm trying to print everything inside "data" to the console. This is the code I got so far:
JsonParser parser = new JsonParser();
JsonObject json = (JsonObject)
parser.parse(adsInsights.toString());
System.out.println(json.get("p1").getAsString() + "\t"
+ json.get("p2").getAsString() + "\t"
+ json.get("p3").getAsString() + "\t"
+ json.get("p4").getAsString() + "\t" +
json.get("p5").getAsString()
);
My problem is: how do I determine which ones to print, without doing a ton of if/elses?
All I need is every variable within "data". is there a method to do this?
EDIT:
First of all, thanks for all the answers.
For future reference I guess, this is what I did:
//getting the keys, which the user has selected. Detailed implementation irrelevant for this matter
String selectedKeys[] = getSelectedKeys();
JsonParser parser = new JsonParser();
JsonObject json = (JsonObject)
parser.parse(adsInsights.toString());
for(int i = 0; i < selectedKeys.length; i++) {
if(json.has(selectedKeys[i])) {
System.out.print(json.get(selectedKeys[i]).getAsString() + "\t");
}
}
System.out.println();
You can iterate over the Json keys no matter which keys are in it and print their values.
JsonParser parser = new JsonParser();
JsonObject json = (JsonObject)
parser.parse(adsInsights.toString());
for (key: json.keys) {
System.out.print(json.get(key).getAsString());
}
// to check if key exists or not. if not, return empty string.
private String getValues(JSONObject jsonObj, String arg) {
return jsonObj.get(arg) != null?(String) jsonObj.get(arg):"";
}
//call getValues function for every key. fetch all keys from keySet Function.
JSONObject check=(JSONObject) obj;
JSONObject data=(JSONObject) check.get("data");
Set<String> keys=data.keySet();
for(String k:keys){
System.out.println(getValues(data,k));
}
Are you building the API as well?
I think a better data structure to return from the API would be to use an array for "data", e.g.
{
"data":[
{ "id": "p1", "value": "value1" },
{ "id": "p2", "value": "value2" },
{ "id": "p3", "value": "value3" },
{ "id": "p4", "value": "value4" },
{ "id": "p5", "value": "value5" }
]
}
That way, the receiving code doesn't have to care about which items are in data, or how many. Instead it can just loop through the array and print whatever happens to be there.

How to get JSON data that contains JSON Object and array both

*I am already getting this JSON object from responce.body(). I want every data inside this separately in variable. I am using java.
{
"Classes":{
"Primary":{
"Classes":{
"1":{
"section":[
"a",
"b"
]
},
"2":{
"sections":[
"a",
"b"
]
}
}
}
}
}
*I know how to get the JSONObject but i dont know how can i get that array inside "section". even if i get that array with JSONArray then how to convert it to JSONObject? or String.
*Note that inside value of "section" array is dynamic, value inside that array is dynamic and can be multiiple from "a" to "z". Also JSONObject inside "Classes"(inside primary) is also dynamic. there can be dynamic and multiple "1","2"... and it is string, It is not necessary that there will be incremental numbers.
After 30 mins of war, I find out your answer just copy this code and paste where you want to use -
Here it is -
String json = "{
"Classes": {
"Primary": {
"Classes": {
"1": {
"section": [
"a",
"b"
]
},
"2": {
"sections": [
"a",
"b"
]
}
}
}
}
}";
try {
JSONObject jsonObject = new JSONObject(json);
Log.d("jsonObj", jsonObject.toString());
JSONObject classJsonObj = jsonObject.optJSONObject("Classes");
JSONObject primaryJsonObj = classJsonObj.optJSONObject("Primary");
JSONObject internalClassJsonObj = primaryJsonObj.optJSONObject("Classes");
if(internalClassJsonObj != null){
int i = 1;
JSONObject dynmaicInternalJsonObj = null;
while (true){
dynmaicInternalJsonObj = internalClassJsonObj.optJSONObject(i+"");
if(dynmaicInternalJsonObj != null){
JSONArray sectionJsonArr = dynmaicInternalJsonObj.optJSONArray("sections");
Log.d("SectionArr", sectionJsonArr.toString());
// Finally you got your section data here...
if(sectionJsonArr != null){
for(int j=0; j<sectionJsonArr.length(); j++){
System.out.println("Dynamic Sections Data is: - " + sectionJsonArr.opt(j));
}
System.out.println("\n\n");
}
}else{
break;
}
i++;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
You've tagged this as java so I can only assume you want a solution for that language.
To use this data it needs to parsed, this means you are converting the data into a more usable type.
Click this to learn how to parse JSON in java
Assuming you need solution in java, use this to get a object classes for your json structure and then convert your json to java objects using libraries like GSON.
Example:
String json = "{\"city\":\"San Jose\", \"state\": \"CA\", \"country\":\"USA\"}";
Gson gson = new Gson();
Place place = gson.fromJson(json, Place.class);
If you are using ionic (typescript or javascript), you can use the below approach
var json = "{
"Classes": {
"Primary": {
"Classes": {
"1": {
"section": [
"a",
"b"
]
},
"2": {
"sections": [
"a",
"b"
]
}
}
}
}
}";
for(let item in json.Classes.Primary.Classes){
console.log(item.sections);
}
If you want to display the same data in frontend using html, use *ngFor
<div *ngFor="let item in json.Classes.Primary.Classes ">
<h5>{{item.sections}}</h5>
</div>
I hope it helps.

Android - How to parse JSONObject and JSONArrays from api.rottentomatoes

so, there's this JSON code. Im trying to get the "abridged_cast".
but its complicated.
its JSONObject
inside JSONArray onside jSONObject Inside JsonArray....
{
"total": 591,
"movies": [
{
"title": "Jack and Jill",
"year": 2011,
"runtime": "",
"release_dates": {
"theater": "2011-11-11"
},
"ratings": {
"critics_score": -1,
"audience_score": 90
},
"synopsis": "",
"posters": {
"thumbnail": "",
"profile": "",
"detailed": "",
"original": ""
},
"abridged_cast": [
{
"name": "Al Pacino",
"characters": []
},
{
"name": "Adam Sandler",
"characters": []
},
{
"name": "Katie Holmes",
"characters": []
}
],
"links": {
"self": "",
"alternate": ""
}
}
],
"links": {
"self": "",
"next": ""
},
"link_template": ""
}
this is my code for getting "title" and "year"
if (response != null) {
try {
// convert the String response to a JSON object,
// because JSON is the response format Rotten Tomatoes uses
JSONObject jsonResponse = new JSONObject(response);
// fetch the array of movies in the response
JSONArray movies = jsonResponse.getJSONArray("movies");
// add each movie's title to an array
movieTitles = new String[movies.length()];
for (int i = 0; i < movies.length(); i++) {
JSONObject movie = movies.getJSONObject(i);
movieTitles[i] = movie.getString("title");
}
hope someone would help me because i cant figure out how to get the abridged_cast"
movies contains an array of "movie" objects. Each one of those objects contains a field abridged_cast that is an array of (let's call them "cast member") objects.
If you're not going to map to a POJO and instead are going through the JSON, you simply need to get that array in your loop after getting movie, and get each "cast member" object from that array in the same manner using another loop.
...
JSONArray cast = movie.getJSONArray("abridged_cast");
for (int j = 0; j < cast.length(); j++) {
JSONObject castMember = cast.getJSONObject(j);
...
}
Edit from comments: Your original question involved how to extract the information from the JSON you have; the above code explains that. It now seems like you're asking a more fundamental programming question around how to use it.
If you're going to use the included org.json classes that come with Android, you now know how to access the information in the returned JSON object. And you could write methods around the parsed JSONObject to access the data as-is using the objects and methods from the json.org package. For example, you could write a "getMovie()" method that took the name of the movie as a string and searched that "movies" array for the right one and returned it as a JSONObject.
Normally you would create classes in Java that encapsulate the data returned in that JSON and use data structures that lend themselves to your access patterns (For example, a Map that conatained all the movies using their names as keys). Using the org.json classes you'll have to instantiate those objects and populate them manually as you parse the JSON like you're doing in your question. If you used either the Gson or Jackson JSON parsing libraries they are capable of taking the JSON you have and mapping all the data to the classes your create and returning them in a single call.
try {
String Movie = null;
String abridged = null;
JSONArray jsonResponse = new JSONArray(response);
for (int i = 0; i< jsonResponse.length(); i++) {
Movie = jsonResponse.getJSONObject(i).getString("movies").toString();
System.out.println("movies="+Movie);
abridged = jsonResponse.getJSONObject(i).getString("abridged_cast").toString();
}
JSONArray jArray = new JSONArray(Movie);
for (int i = 0; i< jArray.length(); i++) {
String title = jArray.getJSONObject(i).getString("title").toString();
System.out.println("title="+title);
}
JSONArray jabridgeArray = new JSONArray(abridged);
for (int i = 0; i< jabridgeArray.length(); i++) {
String title = jabridgeArray.getJSONObject(i).getString("name").toString();
System.out.println("title="+title);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Categories

Resources