# Object in JSON Datei einlesen und als neues Object erzeugen (in ein Object Array)



## julius0205 (7. Okt 2020)

Hi, ich versuche ein als JSON gespeichertes Objekt wieder einzulesen. Ich habe schon in paar Foren eine Antwort gefunden jedoch klappt es irgendwie nicht so ganz. Wahrscheinlich ist irgendwo ein richtig dummer Fehler.
Vllt kann mal jemand drüber schauen und mir ein Tipp oder eine Lösung geben.
Danke!



```
public void load() throws IOException {
        try {
            JsonParser parser = new JsonParser();
            Object obj = parser.parse(new FileReader("Player.json"));
            for (int i = 0; i < 11; i++) {
                JsonObject jsonObject = (JsonObject) obj;
                JsonArray namearr = (JsonArray) jsonObject.get("name");
                JsonArray lifearr = (JsonArray) jsonObject.get("lifePoints");
                JsonArray attackarr = (JsonArray) jsonObject.get("attackPoints");
                JsonArray elementarr = (JsonArray) jsonObject.get("element");
                JsonArray livingarr = (JsonArray) jsonObject.get("living");
                int ap = Integer.parseInt(String.valueOf(attackarr));
                int lp = Integer.parseInt(String.valueOf(lifearr));
                String jname = String.valueOf(namearr);
                Elements jelement = Elements.valueOf(String.valueOf(elementarr));
                boolean jld = livingarr.getAsBoolean();
                //for (Object objInArr : namearr) {
                createPlayer(jld (boolean), jname (String), ap (int), lp (int), jelement (Element_Enum));
                az++;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
```

JSON-Datei:


```
[
    {
        "attackPoints": 12,
        "az": 1,
        "element": "Feuer",
        "infoAll": null,
        "lifePoints": 20,
        "living": true,
        "name": "Test1"
    },
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null
]
```


----------



## kneitzel (7. Okt 2020)

Du liest das Json ja komplett falsch aus. Was Du auszulesen versuchst, ist eher etwas wie:

```
{
  "name": [ ... ],
  "lifePoints": [ ... ],
  "attackPoints": [ ... ],
  "element": [ ... ],
  "living": [ ... ]
}
```

Also ein JSON Objekt mit den elementen name, lifePoints, ..., die dann jeweils ein JSON Array wären. Davon abgesehen sehe ich nicht, wie Du mehrere Elemente ausliest. Du machst 10 mal  genau das Gleiche ...

Aber bei Dir ist das ja ein JSON Array und jedes Element enthält dann name, lifePoints, ....

Somit dürfte dein Object, das Du zurück bekommen hast in obj ein JsonArray sein. Das kannst Du dann auslesen (Du nutzt gson? Oder welche Library nutzt Du? Das würde dann z.B. Iterable<JsonElement> implementieren. Dann könntest Du damit alle Elemente durchgehen und dann bei jedem Element name, lifePoints und so abfragen.)


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> Du liest das Json ja komplett falsch aus. Was Du auszulesen versuchst, ist eher etwas wie:
> 
> ```
> {
> ...


Jo ich benutze Gson hab das in nem Forumbeitrag so gesehen, ich dachte das funktioniert aber ich probiers mal wie du beschrieben hast. Objekte und so sind neu für mich also hab ich noch nicht viel Ahnung davon


----------



## krgewb (7. Okt 2020)

Du verwendest i nirgends.

az wird zwar mit ++ hochgezählt, aber ich weiß nicht, wo du es zuweist. In deinem Beispiel steht ja 1.


----------



## julius0205 (7. Okt 2020)

krgewb hat gesagt.:


> Du verwendest i nirgends.
> 
> az wird zwar mit ++ hochgezählt, aber ich weiß nicht, wo du es zuweist. In deinem Beispiel steht ja 1.


ist in der klasse ganz oben definiert  und i ist nur für die For-Schleife


----------



## kneitzel (7. Okt 2020)

gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:

```
JsonParser parser = new JsonParser();
JsonArray array = (JsonArray) parser.parse(new FileReader("Player.json"));
for (JsonElement elem: array) {
   JsonObject obj = (JsonObject) elem;
   String name = obj.get("name").getAsString();
   ...
}
```

Das aber nur um einen kleinen Ansatz zu geben. Da du auch null statt Elemente im JsonArray hast, musst Du das natürlich abprüfen, ehe Du etwas ausliest. Und die Exceptions sind in dem Code nicht behandelt. Da sollte man dann aber noch aufnehmen, dass man auch den Stacktrace ausgibt (e.printStackTrace()


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:
> 
> ```
> JsonParser parser = new JsonParser();
> ...


danke dir  ich werds wenn ich zeit hab direkt probieren.


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:
> 
> ```
> JsonParser parser = new JsonParser();
> ...



Ich hab jetzt probiert jedoch bekomm ich immer noch einen Fehler.


> class com.google.gson.JsonNull cannot be cast to class com.google.gson.JsonObject (com.google.gson.JsonNull and com.google.gson.JsonObject are in unnamed module of loader 'app')
> java.lang.ClassCastException: class com.google.gson.JsonNull cannot be cast to class com.google.gson.JsonObject (com.google.gson.JsonNull and com.google.gson.JsonObject are in unnamed module of loader 'app')


In dieser Zeile:
JsonObject obj = (JsonObject) elem;


----------



## sascha-sphw (7. Okt 2020)

julius0205 hat gesagt.:


> Ich hab jetzt probiert jedoch bekomm ich immer noch einen Fehler.
> In dieser Zeile:
> JsonObject obj = (JsonObject) elem;



Hat @JustNobody doch erwähnt.


JustNobody hat gesagt.:


> Da du auch null statt Elemente im JsonArray hast, musst Du das natürlich abprüfen, ehe Du etwas ausliest.


----------



## julius0205 (7. Okt 2020)

sascha-sphw hat gesagt.:


> Hat @JustNobody doch erwähnt.


na und wie löse ich das Problem? ich hab halt einfach ne if-abfrage gemacht bevor ich die objekte auslese:
if (obj != null) {}


----------



## kneitzel (7. Okt 2020)

Also dazu erst einmal den Fehler genau betrachten:
"java.lang.ClassCastException: class com.google.gson.JsonNull cannot be cast to class com.google.gson.JsonObject (com.google.gson.JsonNull and com.google.gson.JsonObject are in unnamed module of loader 'app')"

Du versuchst also etwas zu einem JsonObject zu machen, was kein JsonObject ist.

Dabei ist wichtig: Das ist eine NullPointerException - da ist also kein Wert, der null ist, in der Variablen sondern eine Instanz der Klasse JsonNull.

Du kannst also z.B. mit instanceof prüfen, ob die Instanz vom gewünschten Typ ist. Also sowas wie

```
if (elem instanceof JsonObject) {
  JsonObject obj = (JsonObject) elem;
  // ....
}
```
Wichtig ist aber das Verständnis, was Du du in der Variablen hast. Und aus dem Text "null" macht er eben ein JsonNull. Diese Unterscheidung ist wichtig, denn die findet man teilweise auch durchaus an anderen Stellen.


----------



## sascha-sphw (7. Okt 2020)

julius0205 hat gesagt.:


> na und wie löse ich das Problem? ich hab halt einfach ne if-abfrage gemacht bevor ich die objekte auslese:
> if (obj != null) {}


Das Objekt ist ja nicht null, sondern com.google.gson.JsonNull also musst Du überprüfen was für ein Objekt vorliegt bevor du es castest.

Stichwort: instanceof

Edit: Siehe Post oben drüber. :-D


----------



## BestGoalkeeper (7. Okt 2020)

julius0205 hat gesagt.:


> Jo ich benutze Gson




```
@SuppressWarnings("preview")
	public static void main(String[] args) {
		String s = """
				[
				    {
				        "attackPoints": 12,
				        "az": 1,
				        "element": "Feuer",
				        "infoAll": null,
				        "lifePoints": 20,
				        "living": true,
				        "name": "Test1"
				    },
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null,
				    null
				]
				""";
		Gson gson = new Gson();
		ArrayList<HashMap<String, Object>> fromJson = gson.fromJson(s,
				new TypeToken<ArrayList<HashMap<String, Object>>>() { }.getType());
		for (HashMap<String, Object> map : fromJson) {
			if (map != null) {
				for (Map.Entry<String, Object> e : map.entrySet()) {
					System.out.println(e.toString());
				}
			}
		}
	}
```


```
living=true
lifePoints=20.0
infoAll=null
name=Test1
az=1.0
attackPoints=12.0
element=Feuer
```


----------



## julius0205 (7. Okt 2020)

sascha-sphw hat gesagt.:


> Das Objekt ist ja nicht null, sondern com.google.gson.JsonNull also musst Du überprüfen was für ein Objekt vorliegt bevor du es castest.
> 
> Stichwort: instanceof
> 
> Edit: Siehe Post oben drüber. :-D


heißt, ich muss in einer if-abfrage überprüfen ob "obj instanceof Players" ist oder?
Ich habe alle Spieler in einem ObjektArray gespeichert.


----------



## julius0205 (7. Okt 2020)

BestGoalkeeper hat gesagt.:


> ```
> @SuppressWarnings("preview")
> public static void main(String[] args) {
> String s = """
> ...


Zum Glück bist du sehr hilfreich... Was deine Mission ist weiß ich au ned so genau.


----------



## BestGoalkeeper (7. Okt 2020)

julius0205 hat gesagt.:


> Was deine Mission ist weiß ich au ned so genau


Hä was willst du? Ich habe deine Frage beantwortet und nicht mehr/weniger.

Übrigens geht auch `LinkedHashMap` wenn dir die Reihenfolge wichtig ist.


----------



## julius0205 (7. Okt 2020)

BestGoalkeeper hat gesagt.:


> Hä was willst du? Ich habe deine Frage beantwortet und nicht mehr/weniger.
> 
> Übrigens geht auch `LinkedHashMap` wenn dir die Reihenfolge wichtig ist.


Huch tut mir leid. Danke haha das hat so ausgeschaut als ob du einfach meine Frage genommen hättest und unten hin "Wie stelle ich Fragen richtig"


----------



## sascha-sphw (7. Okt 2020)

julius0205 hat gesagt.:


> heißt, ich muss in einer if-abfrage überprüfen ob "obj instanceof Players" ist oder?
> Ich habe alle Spieler in einem ObjektArray gespeichert.


Ich habe meinen Post editiert, da steht siehe Post (https://www.java-forum.org/thema/ob...eugen-in-ein-object-array.189567/post-1233416) von @JustNobody.


----------



## julius0205 (7. Okt 2020)

sascha-sphw hat gesagt.:


> Ich habe meinen Post editiert, da steht siehe Post (https://www.java-forum.org/thema/ob...eugen-in-ein-object-array.189567/post-1233416) von @JustNobody.




```
try {
            JsonParser parser = new JsonParser();
            JsonArray array = (JsonArray) parser.parse(new FileReader("Players.json"));
            for (JsonElement elem : array) {
                JsonObject obj = (JsonObject) elem;
                if (obj instanceof JsonObject) {
                    String name = obj.get("name").getAsString();
                    int lp = obj.get("lifePoints").getAsInt();
                    int ap = obj.get("attackPoints").getAsInt();
                    boolean lod = obj.get("living").getAsBoolean();
                    Elements element = Elements.valueOf(obj.get("element").getAsString());
                    createPlayer(lod, name, ap, lp, element);
                }
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
```

Hab das jetzt so abgeändert dass ich überprüfe ob obj eine instanz von JsonOBject ist. Kommt aber immer noch ein Fehler.


----------



## kneitzel (7. Okt 2020)

Wobei ich mir bei der Lösung eh unsicher bin. Es handelt sich ja um eine Serialisierung von Objekten einer Klasse so ich den TE richtig verstanden habe. Da ist das Einlesen in eine Map evtl. ebenso wenig anzuraten wie eben das manuelle Auslesen wie er es zuerst versucht hat.

Was mir bei seinem createPlayer aufruf auffällt sind dann aber auch noch die Angabe von Typen nach jedem Parameter... Also evtl. ist die Nutzung von JSON jetzt noch etwas zu früh ..

Aber wenn er eine entsprechende Klasse hat a.la. 

```
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Player {
  private int attackPoints;
  private int az;
  private Element_Enum element;
  private String infoAll;
  private int lifePoints;
  private boolean living;
  private String name;
}
```
(Jetzt einfach mal mit Lombok Annotations - aber man kann problemlos Getter/Setter und Konstruktoren selbst schreiben ...)

Dann würde evtl. schon ein einfaches:

```
Gson gson = new Gson();
Player[] players = gson.fromJson(json, Player[].class);
```
reichen um das JSON in ein Array von Player Instanzen zu lesen...


----------



## kneitzel (7. Okt 2020)

julius0205 hat gesagt.:


> ```
> try {
> JsonParser parser = new JsonParser();
> JsonArray array = (JsonArray) parser.parse(new FileReader("Players.json"));
> ...


Die Überprüfung muss kommen, ehe man den Cast versucht. Ich habe mein Beitrag auch noch editiert, denn ich hatte da die falsche Variable geprüft. Du musst prüfen, ob elem instanceof JsonObject ist und nur wenn das der Fall ist, dann kannst Du den Cast zu JsonObject machen.


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> Wobei ich mir bei der Lösung eh unsicher bin. Es handelt sich ja um eine Serialisierung von Objekten einer Klasse so ich den TE richtig verstanden habe. Da ist das Einlesen in eine Map evtl. ebenso wenig anzuraten wie eben das manuelle Auslesen wie er es zuerst versucht hat.
> 
> Was mir bei seinem createPlayer aufruf auffällt sind dann aber auch noch die Angabe von Typen nach jedem Parameter... Also evtl. ist die Nutzung von JSON jetzt noch etwas zu früh ..
> 
> ...



Das heißt ich muss wirklich alles auslesen was in der Datei drin is? Bist jetzt lese ich nur Name, Leben, etc. aus...
Ich versuche es als json zu speichern da man es ja so mit Objekten macht.


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> Die Überprüfung muss kommen, ehe man den Cast versucht. Ich habe mein Beitrag auch noch editiert, denn ich hatte da die falsche Variable geprüft. Du musst prüfen, ob elem instanceof JsonObject ist und nur wenn das der Fall ist, dann kannst Du den Cast zu JsonObject machen.


Danke dir! Jetzt klappt es. Ich hatte die if-Abfrage an der falschen Stelle und eben den kleinen Fehler dass elem & obj vertauscht waren. Danke


----------



## kneitzel (7. Okt 2020)

Also generell liest Du eh die ganze Datei aus. Die Frage ist nur, was Du wirklich brauchst. Wenn Du die Player Instanzen komplett über gson erzeugst, dann haben die natürlich alle Werte aus der Datei. Wenn das nicht das gewünschte Ziel ist, dann müsste man da halt noch weiteren Code schreiben. Aber generell scheint das eine JSON Serialisierung zu sein und das machen die Libraries von ganz alleine ohne dass man da irgendwas groß an Code manuell schreiben muss.

Aber es spricht nichts dagegen, diesen manuellen Weg zu gehen. Das kann durchaus eine interessante Übung sein.


----------



## BestGoalkeeper (7. Okt 2020)

JustNobody hat gesagt.:


> @Data @AllArgsConstructor @NoArgsConstructor


Unsinnig. 

Da hat einer Gson nicht verstanden...


----------



## kneitzel (7. Okt 2020)

BestGoalkeeper hat gesagt.:


> Unsinnig.
> 
> Da hat einer Gson nicht verstanden...


Wie kommst Du jetzt zu so einer Aussage? Ich kann ja verstehen, dass Du die Annotations nicht kennst, aber dafür habe ich diese auch kurz erläutert: "(Jetzt einfach mal mit Lombok Annotations - aber man kann problemlos Getter/Setter und Konstruktoren selbst schreiben ...)"

Das ist also eine einfache, triviale Entity und die Getter / Setter / Konstruktoren lasse ich mir von Lombok generieren. Wo Du bei der Entity den Zusammenhang zu GSON sehen willst, das entzieht sich mir, denn jeder, der etwas mit GSON Instanzen serialisiert, der sollte wissen, dass da keine speziellen Annotations notwendig sind. (Siehe z.B. https://sites.google.com/site/gson/gson-user-guide#TOC-Primitives-Examples - einfaches Beispiel - ganz ohne jede Annotation)

Daher stellt sich jetzt die Frage, wo Du Probleme gesehen hast ...


----------



## BestGoalkeeper (7. Okt 2020)

JustNobody hat gesagt.:


> Daher stellt sich jetzt die Frage, wo Du Probleme gesehen hast


In Lombok. Man muss doch nicht noch eine Lib. überstülpen, wenn er Gson schon nicht ganz versteht...


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> Wie kommst Du jetzt zu so einer Aussage? Ich kann ja verstehen, dass Du die Annotations nicht kennst, aber dafür habe ich diese auch kurz erläutert: "(Jetzt einfach mal mit Lombok Annotations - aber man kann problemlos Getter/Setter und Konstruktoren selbst schreiben ...)"
> 
> Das ist also eine einfache, triviale Entity und die Getter / Setter / Konstruktoren lasse ich mir von Lombok generieren. Wo Du bei der Entity den Zusammenhang zu GSON sehen willst, das entzieht sich mir, denn jeder, der etwas mit GSON Instanzen serialisiert, der sollte wissen, dass da keine speziellen Annotations notwendig sind. (Siehe z.B. https://sites.google.com/site/gson/gson-user-guide#TOC-Primitives-Examples - einfaches Beispiel - ganz ohne jede Annotation)
> 
> Daher stellt sich jetzt die Frage, wo Du Probleme gesehen hast ...


jedenfalls hab ich jetzt doch noch eine Frage 
Wenn ich mehrere Spieler erstelle und diese abspeichere und dann auslesen lasse wird nur der erste eingelesen.
Muss ich da noch irgendwo eine Schleife einbauen?

--> Mein Fehler ich glaube ich habe einen Fehler in ner anderen Methode


----------



## kneitzel (7. Okt 2020)

BestGoalkeeper hat gesagt.:


> In Lombok. Man muss doch nicht noch eine Lib. überstülpen, wenn er Gson schon nicht ganz versteht...



a) Deine Unterstellung, dass ich GSON nicht verstanden habe, ist Unsinn wenn Du nur mit Lombok ein Problem hast.
b) Ist die Aussage von mir klar: Schreib einfach Getter/Setter/Konstruktoren selbst - niemand braucht Lombok. (Das ist übrigens eines der wichtigsten Features von Lombok: delombok: Wenn jemand ein Problem mit Lombok im Projekt hat, dann kann er es mit einem Aufruf rausschmeißen!)



julius0205 hat gesagt.:


> jedenfalls hab ich jetzt doch noch eine Frage
> Wenn ich mehrere Spieler erstelle und diese abspeichere und dann auslesen lasse wird nur der erste eingelesen.
> Muss ich da noch irgendwo eine Schleife einbauen?
> 
> --> Mein Fehler ich glaube ich habe einen Fehler in ner anderen Methode



Schleife hast Du ja - Du hast eine for each Schleife, die durch alle Elemente durch geht. Aber zumindest im Beispiel war auch nur ein Spieler enthalten - der Rest war ja null.


----------



## julius0205 (7. Okt 2020)

JustNobody hat gesagt.:


> a) Deine Unterstellung, dass ich GSON nicht verstanden habe, ist Unsinn wenn Du nur mit Lombok ein Problem hast.
> b) Ist die Aussage von mir klar: Schreib einfach Getter/Setter/Konstruktoren selbst - niemand braucht Lombok. (Das ist übrigens eines der wichtigsten Features von Lombok: delombok: Wenn jemand ein Problem mit Lombok im Projekt hat, dann kann er es mit einem Aufruf rausschmeißen!)
> 
> 
> ...


Der Fehler lag bei mir  Trz danke 
Und Jungs beeft euch nicht wer mehr Ahnung hat. Getter und Setter hab ich ja eh


----------

