2
\$\begingroup\$

First of all, here is an overview of my application. I want to create a multiple-choice app, on android, using data stored on a remote MySQL database. The DB has 100 questions that will appear in random order.

My php script returns a JSON array with the following results

[
 {
    "id": 1,
    "Question": " blahblahblahblahblah?"
},
{
    "id": 2,
    "Question": "blehblehblehblehblehblehblehblehbleh?"
},
]

Since the Question table on my database has integers and strings I thought that it would be a better approach to copy the information of the JSON Objects to different instances of a Class Question. I want the JSONArray to be created once in order to avoid multiple requests to the server.That's why I wrote the following code:

public class Question {
    int question_id;
    String question_txt ;
    JSONArray json ;


public int setQuestion_id(int i) {
    try {this.question_id = this.json.getJSONObject(i).getInt("id");}
    catch (JSONException e) {e.printStackTrace();}

    return question_id;
}

public String setQuestion_txt(int i) {
    try {this.question_txt=this.json.getJSONObject(i).getString("Question");} 
    catch (JSONException e) {e.printStackTrace();}

    return question_txt;
}

public JSONArray setJson()throws JSONException, IOException {
    java.net.HttpURLConnection connection = null;
    URL url = new URL("url_to_my.php");
    connection = (java.net.HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Content-length", "0");
    connection.setUseCaches(false);
    connection.setConnectTimeout(0);
    connection.setReadTimeout(0);
    connection.connect();
    int status = connection.getResponseCode();
    JSONArray json = null;


    switch (status) {
        case 200:
        case 201:

            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;

            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }

            this.json = new JSONArray(sb.toString());
            br.close();
    }
    return this.json;

}

}

What I tried doing is creating an ArrayList questionnaire and add to it different instances of the Class Question with different values.

ArrayList<Question> questionnaire = new ArrayList<Question>();
Question q = new Question();    

for(int i=0; i< q.setJson().length() ;i++){
    Question newQuestion = new Question();
             newQuestion.json = q.json;
             newQuestion.setQuestion_id(i);
             newQuestion.setQuestion_txt(i);
             questionnaire.add(newQuestion);}

Everything seems to work fine, at least for now. Later on, I want the JSON result to return more information like the possible answers and which is the correct one.

\$\endgroup\$
1
1
\$\begingroup\$

Good effort to get your code working so far. But your code is highly unusual.

You've got the class Question which has an id and question_txt, but each Question also has a reference to a JSONArray of all the questions. Worse than that, for each Question, when you create a new Question and set its reference to all questions, it will come from the API each time.

You've recognised that the behaviour of getting Questions from the API might belong in the Question class (or related class), instead of forcing main (or whatever consumer) to know the details of the API. But it's surely not the responsibility of a single Question instance to fetch all the Questions.

You want the class Question to hold it's data first (and later, some behaviour), so here's a typical data class.

public class Question {

    private int id;
    private String text;

    public Question (int i, String s) {
        this.id = i;
        this.text = s;
    }

    public int getId() {
        return id;
    }

    public String getText() {
        return text; 
    }

}

You'll see this type of class referred to as Java Bean or POJO. In this case, because we've used private and only provided get methods, this is a read-only object after its been created.

Then add some behaviour to the class (meaning we're going to use the static keyword) for retrieving the questions:

public static List<Question> fetchQuestions () throws JSONException, IOException {

    HttpURLConnection connection = (HttpURLConnection) new URL("url_to_my.php").openConnection();
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Content-length", "0");
    connection.setUseCaches(false);
    connection.setConnectTimeout(0);
    connection.setReadTimeout(0);
    connection.connect();
    int status = connection.getResponseCode();
    if (!(status == 200 || status == 201)) {
        throw new IOException("Bad status code: " + status);
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = br.readLine()) != null) {
        sb.append(line + "\n");
    }
    br.close();
    String response = sb.toString();

    List<Question> questions = new ArrayList<Question>();
    for (Object arrayItem: new JSONArray(response)) {
        JSONObject questionAsJSON = (JSONObject) arrayItem; // throws on unexpected response format
        questions.add(new Question(questionAsJSON.getInt("id"), 
                questionAsJSON.getString("Question")));
    }

    return questions;

}

And then when we want to grab the questions from the API, it's just a case of invoking the static method:

List<Question> questionnaire = Question.fetchQuestions();
\$\endgroup\$
2
  • \$\begingroup\$ Hi Jeremy, it seems like you can't iterate with for each loop a JSONArray. Therefore I made some modifications to your code (Check my Edit). Other than that, your code is what I wanted to do from the beginning, but I couldn't figure how. \$\endgroup\$
    – Volpym
    Oct 5 '19 at 14:18
  • \$\begingroup\$ JSONArray is Iterable for me. Could be a version difference? I'm using <dependency>groupId>org.json</groupId><artifactId>json</artifactId><version>20190722</version></dependency> \$\endgroup\$ Oct 5 '19 at 22:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.