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

julius0205

Mitglied
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!


Java:
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:

JSON:
[
    {
        "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
]
 
Du liest das Json ja komplett falsch aus. Was Du auszulesen versuchst, ist eher etwas wie:
Code:
{
  "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.)
 
Du liest das Json ja komplett falsch aus. Was Du auszulesen versuchst, ist eher etwas wie:
Code:
{
  "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.)
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
 
Du verwendest i nirgends.

az wird zwar mit ++ hochgezählt, aber ich weiß nicht, wo du es zuweist. In deinem Beispiel steht ja 1.
 
gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:
Code:
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()😉
 
gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:
Code:
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()😉
danke dir 🙂 ich werds wenn ich zeit hab direkt probieren.
 
gson ist ok - der dann nur noch einmal kurz, wie es vermutlich aussehen könnte:
Code:
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()😉

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;
 
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
Java:
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.
 
Zuletzt bearbeitet von einem Moderator:
Jo ich benutze Gson
Java:
	@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());
				}
			}
		}
	}
Code:
living=true
lifePoints=20.0
infoAll=null
name=Test1
az=1.0
attackPoints=12.0
element=Feuer
 
Java:
    @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());
                }
            }
        }
    }
Code:
living=true
lifePoints=20.0
infoAll=null
name=Test1
az=1.0
attackPoints=12.0
element=Feuer
Zum Glück bist du sehr hilfreich... Was deine Mission ist weiß ich au ned so genau.
 
Java:
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.
 
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.
Code:
@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:
Code:
Gson gson = new Gson();
Player[] players = gson.fromJson(json, Player[].class);
reichen um das JSON in ein Array von Player Instanzen zu lesen...
 
Java:
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.
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.
 
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.
Code:
@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:
Code:
Gson gson = new Gson();
Player[] players = gson.fromJson(json, Player[].class);
reichen um das JSON in ein Array von Player Instanzen zu lesen...

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.
 
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
 
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.
 
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 ...
 
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
 
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!)

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.
 
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!)



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.
Der Fehler lag bei mir 😀 Trz danke
Und Jungs beeft euch nicht wer mehr Ahnung hat. Getter und Setter hab ich ja eh
 

Zurück
Oben