Warum wirft Gson fromJson eine JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?

Lesezeit: 4 Minuten

Warum wirft Gson fromJson eine JsonSyntaxException Expected BEGIN OBJECT but was
Sotirios Delimanolis

(Dieser Beitrag soll eine kanonische Frage mit einer Beispielantwort unten sein.)


Ich versuche, einige JSON-Inhalte in einen benutzerdefinierten POJO-Typ mit zu deserialisieren Gson#fromJson(String, Class).

Dieses Stück Code

import com.google.gson.Gson;

public class Sample {
    public static void main(String[] args) {
        String json = "{\"nestedPojo\":[{\"name\":null, \"value\":42}]}";
        Gson gson = new Gson();
        gson.fromJson(json, Pojo.class);
    }
}

class Pojo {
    NestedPojo nestedPojo;
}

class NestedPojo {
    String name;
    int value;
}

wirft die folgende Ausnahme

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.Gson.fromJson(Gson.java:810)
    at com.google.gson.Gson.fromJson(Gson.java:775)
    at com.google.gson.Gson.fromJson(Gson.java:724)
    at com.google.gson.Gson.fromJson(Gson.java:696)
    at com.example.Sample.main(Sample.java:23)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189)
    ... 7 more

Warum kann Gson meinen JSON-Text nicht richtig in meinen POJO-Typ konvertieren?

  • Es könnte sich lohnen, eine zweite Antwort für den inversen Fehler hinzuzufügen. Erwartetes Array, war aber Objekt

    – OneCricketeer

    8. Juli 2018 um 19:21 Uhr

Warum wirft Gson fromJson eine JsonSyntaxException Expected BEGIN OBJECT but was
Sotirios Delimanolis

Wie die Ausnahmemeldung besagt

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo

Beim Deserialisieren erwartete Gson ein JSON-Objekt, fand aber ein JSON-Array. Da es nicht von einem zum anderen konvertieren konnte, hat es diese Ausnahme ausgelöst.

Das JSON-Format wird beschrieben Hier. Kurz gesagt definiert es die folgenden Typen: Objekte, Arrays, Strings, Zahlen, nullund die booleschen Werte true und false.

In Gson (und den meisten JSON-Parsern) gibt es die folgenden Zuordnungen: Eine JSON-Zeichenfolge wird einem Java zugeordnet String; Eine JSON-Nummer wird einem Java zugeordnet Number Art; ein JSON-Array wird a zugeordnet Collection Typ oder ein Array-Typ; Ein JSON-Objekt wird einem Java zugeordnet Map Typ oder, in der Regel, eine benutzerdefinierte POJO Typ (vorher nicht erwähnt); null Karten zu Java nullund die booleschen Werte werden Java zugeordnet true und false.

Gson durchläuft den von Ihnen bereitgestellten JSON-Inhalt und versucht, ihn in den entsprechenden angeforderten Typ zu deserialisieren. Wenn der Inhalt nicht übereinstimmt oder nicht in den erwarteten Typ konvertiert werden kann, wird eine entsprechende Ausnahme ausgelöst.

In Ihrem Fall haben Sie das folgende JSON bereitgestellt

{
    "nestedPojo": [
        {
            "name": null,
            "value": 42
        }
    ]
}

An der Wurzel ist dies ein JSON-Objekt, das ein Mitglied mit dem Namen enthält nestedPojo das ist ein JSON-Array. Dieses JSON-Array enthält ein einzelnes Element, ein weiteres JSON-Objekt mit zwei Mitgliedern. In Anbetracht der zuvor definierten Zuordnungen würden Sie erwarten, dass dieser JSON-Code einem Java-Objekt zugeordnet wird, das ein benanntes Feld hat nestedPojo von einigen Collection oder Array-Typ, wobei dieser Typ zwei benannte Felder definiert name und valuebzw.

Allerdings haben Sie Ihre definiert Pojo Typ als mit einem Feld

NestedPojo nestedPojo;

das ist weder ein Array-Typ noch ein Collection Art. Gson kann den entsprechenden JSON-Code für dieses Feld nicht deserialisieren.

Stattdessen haben Sie 3 Möglichkeiten:

  • Ändern Sie Ihr JSON so, dass es dem erwarteten Typ entspricht

    {
        "nestedPojo": {
            "name": null,
            "value": 42
        }
    }
    
  • Ändere dein Pojo Typ erwarten a Collection oder Array-Typ

    List<NestedPojo> nestedPojo; // consider changing the name and using @SerializedName
    NestedPojo[] nestedPojo;
    
  • Schreiben und registrieren Sie einen benutzerdefinierten Deserializer für NestedPojo mit eigenen Parsing-Regeln. Zum Beispiel

    class Custom implements JsonDeserializer<NestedPojo> {
        @Override
        public NestedPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            NestedPojo nestedPojo = new NestedPojo();
            JsonArray jsonArray = json.getAsJsonArray();
            if (jsonArray.size() != 1) {
                throw new IllegalStateException("unexpected json");
            }
            JsonObject jsonObject = jsonArray.get(0).getAsJsonObject(); // get only element
            JsonElement jsonElement = jsonObject.get("name");
            if (!jsonElement.isJsonNull()) {
                nestedPojo.name = jsonElement.getAsString();
            }
            nestedPojo.value = jsonObject.get("value").getAsInt();
            return nestedPojo;
        }
    }
    
    Gson gson = new GsonBuilder().registerTypeAdapter(NestedPojo.class, new Custom()).create();
    

class Pojo {
  NestedPojo nestedPojo;
}

In Ihrem JSON haben Sie ein Array von nestedPojo, also ändern Sie entweder den Code

  NestedPojo[] nestedPojo;

oder Sie ändern den JSON-String

String json = "{\"nestedPojo\":{\"name\":null, \"value\":42}}";

964910cookie-checkWarum wirft Gson fromJson eine JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy