# Json reader



## LouCyphre (24. Okt 2021)

Hallo,

ich versuche aus einem .json Daten zu lesen.


```
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

class Scratch {
    public static void main(String[] args) {

        final File questionFile = new File("/questions.json");
        Scratch scratch = new Scratch();
        System.out.println(scratch.readQuestion().question);

    }
    public void readQuestion() {

        try {

            JsonElement questionElement = JsonParser.parseReader(new FileReader(questionFile));
            JsonObject questionObject = questionElement.getAsJsonObject();

            JsonArray jsonArrayOfQuestions = questionObject.get("questions").getAsJsonArray();

            for (JsonElement qElement : jsonArrayOfQuestions){
                JsonObject qJsonObject = qElement.getAsJsonObject();

                String question = qJsonObject.get("question").getAsString();



            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}
```

Soweit so schlecht. Der FileReader kann das questionFile nicht finden. Die .json ist im resoureces Ordner abglegt. Soviel zum ersten Problem. Da ich aus dem File nichts lesen kann, kann ich gerade auch nicht abwegen ob der Rest überhaupt so klappt.


```
{"questions":[
  {
    "question": "Was ist kein Buchstabe?",
    "answers" : "A" // hier eigentlich noch 3 weitere Strings
  },
  {
    "question" :"Andere Frage ...?",
    "answers" : "..."
  }
 ]
}
```

So ist der grobe Aufbau der Json. Hier haber ich noch das Problem, das answers eigentlich eine Liste, hier aber nur was einzelnes erwartet wird. Wie kann ich daraus eine Liste machen? 


Danke, 
Lou


----------



## mihe7 (24. Okt 2021)

Nicht den FileReader sondern einen InputStreamReader mit getClass().getResourceAsStream() verwenden (für Details https://www.java-forum.org/thema/classpath-ressourcen-ides-und-build-systeme.194131/)


----------



## LouCyphre (24. Okt 2021)

Okay, danke erstmal. hatten wir ja schonmal das Thema.


```
InputStreamReader questionFile = getClass().getResourceAsStream("questions.json");

JsonElement questionElement = JsonParser.parseReader(new InputStreamReader(questionFile));
```

So gehts leider auch nicht.

es wird mir getClass() rot unterstrichen


----------



## mihe7 (24. Okt 2021)

Ja, weil Deine Methode static ist. In dem Fall wäre es Scratch.class.getResourceAsStream(...). Außerdem liefert das keinen InputStreamReader sondern einen InputStream.


----------



## LouCyphre (24. Okt 2021)

mihe7 hat gesagt.:


> Ja, weil Deine Methode static ist


Die Main jetzt?


```
InputStream questionFile = Scratch.class.getResourceAsStream("questions.json");

JsonElement questionElement = JsonParser.parseReader(new InputStream(questionFile));
```

bei questionElement stimmt aber immer noch was nicht. 

Ist das generell so trotzdem der richtige Ansatz oder ist das Murcks?
Hab ich ich aus einem Tutorial und weiß nicht wie ich das bewerten soll...


----------



## mihe7 (24. Okt 2021)

LouCyphre hat gesagt.:


> Die Main jetzt?


Ja.



LouCyphre hat gesagt.:


> bei questionElement stimmt aber immer noch was nicht.




```
InputStream questionFile = Scratch.class.getResourceAsStream("questions.json");
JsonElement questionElement = JsonParser.parseReader(new InputStreamReader(questionFile));
```


----------



## LouCyphre (24. Okt 2021)

mihe7 hat gesagt.:


> JsonElement questionElement = JsonParser.parseReader(new InputStreamReader(questionFile));


Leider nicht, hatte ich zuvor schon versucht, deswegen der non-sense Ansatz mit InputStream


----------



## mihe7 (24. Okt 2021)

Was heißt "Leider nicht"? Gibt es eine Exception? Was passiert?


----------



## LouCyphre (24. Okt 2021)

Habs jetzt erstmal so zu Testzwecken "hinbekommen".


```
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.*;

class Scratch {
    public static void main(String[] args) {

        Scratch scratch = new Scratch();
        scratch.readQuestion();

    }
    public void readQuestion() {
        InputStream questionFile = Scratch.class.getResourceAsStream("questions.json");

        JsonElement questionElement = JsonParser.parseReader(new InputStreamReader(questionFile));
        JsonObject questionObject = questionElement.getAsJsonObject();

        JsonArray jsonArrayOfQuestions = questionObject.get("questions").getAsJsonArray();

        for (JsonElement qElement : jsonArrayOfQuestions){
            JsonObject qJsonObject = qElement.getAsJsonObject();

            String question = qJsonObject.get("question").getAsString();
            System.out.println(question);


        }

    }
}
```

Das File scheint er erstmal einzulesen. Bekomme nur Fehler für den JSON Syntax

EDIT: Jetzt klappt es auch. Der Built war noch Schuld. Rebuild hats gebracht.


----------



## mihe7 (24. Okt 2021)

LouCyphre hat gesagt.:


> Bekomme nur Fehler für den JSON Syntax


OK, das ist eine andere Baustelle.


----------



## LouCyphre (24. Okt 2021)

mihe7 hat gesagt.:


> OK, das ist eine andere Baustelle.


Richtig.

Ich würde dann nämlich gern sowas machen


```
//...

 String question = qJsonObject.get("question").getAsString();
            List<String> answers = new ArrayList<>();
            answers = qJsonObject.get("answers").getAsList(); // getasList() gibts nicht
                                                              // hab ich mir nur gewünscht

            Card card = new Card(question, answers);
```

Die Frage ist jetzt noch, wie bekomme ich answers im .json zu einer Liste formatiert?


----------



## mihe7 (24. Okt 2021)

```
{
  "question": "Wie viele Ecken hat ein Quadrat?"
  "answers": [
      "Eine", "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben", "Acht"
  ]
}
```


----------



## LouCyphre (25. Okt 2021)

LouCyphre hat gesagt.:


> answers = qJsonObject.get("answers").getAsList();


Hat jemand dazu noch einen Vorschlag?
Ich brauche das als Array, da der Konstruktor von Card das so braucht.
Die IDE hat vorgeschlagen, dass direkt in der Klasse als JsonArray zu deklarieren. Das ist aber nicht mehr so modular wie ich es gern hätte...


----------



## mrBrown (25. Okt 2021)

getAsJsonArray nutzen, dann bekommt du ein JsonArray. Über dieses dann iterieren, und mit get und getAsString die einzelnen Elemente als String holen und mit diesen dann eine passende Liste füllen.


----------



## Oneixee5 (25. Okt 2021)

So ein rumgedaddel mit JSON-Objekten ist gar nicht nötig:

```
public class JsonTest {

    private static class Question {

        private String question;
        private String[] answers;

        public String getQuestion() {
            return this.question;
        }
        public void setQuestion(final String question) {
            this.question = question;
        }
        public String[] getAnswers() {
            return this.answers;
        }
        public void setAnswers(final String[] answers) {
            this.answers = answers;
        }

    }

    public static void main(final String[] args) throws NumberFormatException, IOException {
        final String json = """
                {
                  "question": "Wie viele Ecken hat ein Quadrat?",
                  "answers": [
                      "Eine", "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben", "Acht"
                  ]
                }
                """;
        final ObjectMapper mapper = new ObjectMapper();
        final Question question = mapper.readValue(json, Question.class);

        System.out.println(question.getQuestion());

        final BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        final int n = Integer.parseInt(r.readLine());
        System.out.println(question.getAnswers()[n-1]);
    }

}
```


----------



## Oneixee5 (25. Okt 2021)

```
public class JsonTest {

...
import com.fasterxml.jackson.databind.ObjectMapper;
...

    public static final class Questions {

        private List<Question> questions;

        public List<Question> getQuestions() {
            return this.questions;
        }

        public void setQuestions(final List<Question> questions) {
            this.questions = questions;
        }

    }

    private static class Question {

        private String question;
        private String[] answers;

        public String getQuestion() {
            return this.question;
        }
        public void setQuestion(final String question) {
            this.question = question;
        }
        public String[] getAnswers() {
            return this.answers;
        }
        public void setAnswers(final String[] answers) {
            this.answers = answers;
        }

    }

    public static void main(final String[] args) throws NumberFormatException, IOException {
        final String json = """
                {
                    "questions":[
                        {
                            "question": "Wie viele Ecken hat ein Quadrat?",
                            "answers": [ "Eine", "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben", "Acht" ]
                        },
                        {
                            "question": "Was ist kein Buchstabe? 1: A, 2: 99, 3: Q ",
                            "answers" : [ "falsch", "richtig", "falsch" ]
                          }

                    ]
                }
                """;
        final ObjectMapper mapper = new ObjectMapper();
        final Questions questions = mapper.readValue(json, Questions.class);

        try (BufferedReader r = new BufferedReader(new InputStreamReader(System.in))) {
            for (final Question question : questions.getQuestions()) {
                System.out.println(question.getQuestion());
                final int n = Integer.parseInt(r.readLine());
                System.out.println(question.getAnswers()[n-1]);
            }
        }
    }

}
```


----------

