JsonMappingException: Kein START_ARRAY-Token mehr


111

Gegeben die folgende .json-Datei:

[
    {
        "name" : "New York",
        "number" : "732921",
        "center" : [
                "latitude" : 38.895111, 
                "longitude" : -77.036667
            ]
    },
    {
        "name" : "San Francisco",
        "number" : "298732",
        "center" : [
                "latitude" : 37.783333, 
                "longitude" : -122.416667
            ]
    }
]

Ich habe zwei Klassen vorbereitet, um die enthaltenen Daten darzustellen:

public class Location {
    public String name;
    public int number;
    public GeoPoint center;
}

...

public class GeoPoint {
    public double latitude;
    public double longitude;
}

Um den Inhalt aus der .json-Datei zu analysieren, verwende ich Jackson 2.2.x und bereite die folgende Methode vor:

public static List<Location> getLocations(InputStream inputStream) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        TypeFactory typeFactory = objectMapper.getTypeFactory();
        CollectionType collectionType = typeFactory.constructCollectionType(
                                            List.class, Location.class);
        return objectMapper.readValue(inputStream, collectionType);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Solange ich die centerEigenschaft weglasse, können alle Inhalte analysiert werden. Wenn ich jedoch versuche, die Geokoordinaten zu analysieren, wird die folgende Fehlermeldung angezeigt:

com.fasterxml.jackson.databind.JsonMappingException: Instanz von
com.example.GeoPoint kann nicht aus dem START_ARRAY-Token unter [Quelle: android.content.res.AssetManager$AssetInputStream@416a5850; Zeile: 5, Spalte: 25]
(durch Referenzkette: com.example.Location ["center"])


Warum benutzt du Jackson, wenn du es einfach mit json parser analysieren kannst
Shashank Agarwal

4
Ihre JSON-Zeichenfolge ist fehlerhaft. Der Typ von centerist ein Array ungültiger Objekte. Versuchen Sie zu ersetzen [und ]mit {und }in dem JSON - String um longitudeund latitudeso werden sie Objekte sein.
Katona

1
@ Katona Danke. Können Sie bitte Ihren Kommentar in eine Antwort umwandeln, damit ich die Frage schließen kann?!
JJD

Antworten:


75

Ihre JSON-Zeichenfolge ist fehlerhaft: Der Typ von centerist ein Array ungültiger Objekte. Ersetzen Sie [und ]mit {und }in der JSON-Zeichenfolge longitudeund latitudeso werden sie Objekte:

[
    {
        "name" : "New York",
        "number" : "732921",
        "center" : {
                "latitude" : 38.895111, 
                "longitude" : -77.036667
            }
    },
    {
        "name" : "San Francisco",
        "number" : "298732",
        "center" : {
                "latitude" : 37.783333, 
                "longitude" : -122.416667
            }
    }
]

1
Das gleiche Problem hatte ich, aber es war verrückt, da es in Jackson 2.6.3v einen völlig anderen verrückten Fehler gab und mit 2.9.8v alles funktionierte. Verdammt, diese Serialisierungsfehler sind so nervig.
BrebDev

114

JsonMappingException: out of START_ARRAY tokenDie Ausnahme wird vom Jackson-Objekt-Mapper ausgelöst, da er Object {}eine Array [{}]Antwort erwartet, während er eine Antwort gefunden hat.

Dies kann durch Ersetzen Objectdurch Object[]im Argument für gelöst werden geForObject("url",Object[].class). Verweise:

  1. Ref.1
  2. Ref.2
  3. Ref.3

9

Ich habe dieses Problem so sortiert, dass der JSON von JSONLint.com überprüft und dann korrigiert wurde. Und das ist Code für das gleiche.

String jsonStr = "[{\r\n" + "\"name\":\"New York\",\r\n" + "\"number\": \"732921\",\r\n"+ "\"center\": {\r\n" + "\"latitude\": 38.895111,\r\n"  + " \"longitude\": -77.036667\r\n" + "}\r\n" + "},\r\n" + " {\r\n"+ "\"name\": \"San Francisco\",\r\n" +\"number\":\"298732\",\r\n"+ "\"center\": {\r\n" + "    \"latitude\": 37.783333,\r\n"+ "\"longitude\": -122.416667\r\n" + "}\r\n" + "}\r\n" + "]";

ObjectMapper mapper = new ObjectMapper();
MyPojo[] jsonObj = mapper.readValue(jsonStr, MyPojo[].class);

for (MyPojo itr : jsonObj) {
    System.out.println("Val of name is: " + itr.getName());
    System.out.println("Val of number is: " + itr.getNumber());
    System.out.println("Val of latitude is: " + 
        itr.getCenter().getLatitude());
    System.out.println("Val of longitude is: " + 
        itr.getCenter().getLongitude() + "\n");
}

Hinweis: MyPojo[].classIst die Klasse mit Getter und Setter von JSON-Eigenschaften.

Ergebnis:

Val of name is: New York
Val of number is: 732921
Val of latitude is: 38.895111
Val of longitude is: -77.036667
Val of name is: San Francisco
Val of number is: 298732
Val of latitude is: 37.783333
Val of longitude is: -122.416667

1
Dies hat das Problem behoben, das ich seit Tagen habe. Keine anderen Antworten machten Sinn. Für alle anderen, die den gleichen Fehler haben. Es ist erwähnenswert, dass Sie mehrere Objekte zurückgeben müssen, wenn Ihr JSON mehrere Objekte enthält. Ich hatte MyObject zurückgegeben, wo ich MyObject []
Aaria

8

Wie gesagt, der JsonMappingException: out of START_ARRAY tokenJackson Object Mapper löst eine Ausnahme aus, da er eine erwartet, Object {}während er eine Array [{}]Antwort gefunden hat.

Eine einfachere Lösung könnte darin bestehen, die Methode getLocationsdurch Folgendes zu ersetzen :

public static List<Location> getLocations(InputStream inputStream) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        TypeReference<List<Location>> typeReference = new TypeReference<>() {};
        return objectMapper.readValue(inputStream, typeReference);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Auf der anderen Seite, wenn Sie kein Pojo wie haben Location, könnten Sie verwenden:

TypeReference<List<Map<String, Object>>> typeReference = new TypeReference<>() {};
return objectMapper.readValue(inputStream, typeReference);

1
Vielen Dank, dass Sie diese alternative Implementierung geteilt haben. Können Sie feststellen, ob die Verwendung von CollectionTypevs. Vor- oder Nachteile hat TypeReference?
JJD

1
TypeReferenceDie Syntax ist viel kürzer als die andere. Ich bin mir nicht sicher, ob es in einigen Fällen eine Gegenanzeige im Zusammenhang mit der Löschung geben könnte ... aber in meiner Welt TypeReferenceist es einfach einfacher zu verwenden und zu verstehen.
freedev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.