2013-10-12 25 views
32

Angesichts der folgenden .json Datei:JsonMappingException: aus START_ARRAY Token

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

vorbereitet ich zwei Klassen 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 bereitete 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 center Eigenschaft weglassen, kann der gesamte Inhalt geparst werden. Allerdings, wenn ich versuche, die Geo-Koordinaten I mit der folgenden Fehlermeldung am Ende zu analysieren:

com.fasterxml.jackson.databind.JsonMappingException: Kann nicht deserialisieren Instanz
com.example.GeoPoint aus START_ARRAY-Token bei [Quelle: [email protected]; Linie: 5, Säule: 25]
(durch die Referenzkette: com.example.Location [ "center"])

+0

warum Sie verwenden Jackson, wenn Sie es einfach mit JSON-Parser analysieren können –

+3

Ihre JSON-Zeichenfolge ist fehlerhaft, der Typ von "Center" ist ein Array von ungültigen Objekten.Versuchen Sie, '[' '' '' '' '' '' '' '' 'in der JSON-Zeichenfolge um' longitude' und 'latitude' zu ​​ersetzen, damit sie Objekte sind. – Katona

+0

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

Antwort

31

Ihr JSON String ungültig ist: die Art der center ist ein Array von ungültigen Gegenständen. Ersetzen [ und ] mit { und } im JSON-String um longitude und latitude so werden sie Objekte sein:

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

JsonMappingException: out of START_ARRAY token Ausnahme von Jackson Objekt Mapper geworfen wird, da es eine Object {} hat erwartet, während es eine Array [{}] als Antwort gefunden.

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

  1. Ref.1
  2. Ref.2
  3. Ref.3
+0

danke, grundlegende aber notwendige Informationen –

+0

Das hat bei mir funktioniert! Ich hatte eine Product.class und ich habe gerade Product []. Class hinzugefügt. Bam! Arbeiten. Danke Abhijeet! – Jonathan

1

Wie gesagt, JsonMappingException: out of START_ARRAY token Ausnahme von Jackson Objekt Mapper geworfen wird, wie es eine Object {} erwartet, während es eine Array [{}] in Reaktion gefunden.

Eine einfachere Lösung könnte das Verfahren ersetzen getLocations mit:

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 wie Location keine pojo haben, könnten Sie verwenden:

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

Vielen Dank für den Austausch dieser alternativen Implementierung. Können Sie feststellen, ob es Vor- oder Nachteile gibt, wenn Sie 'CollectionType' und' TypeReference' verwenden? – JJD

+0

Die 'TypeReference'-Syntax ist viel kürzer als die andere. Nicht sicher, ob es in einigen Fällen eine Gegenanzeige im Zusammenhang mit dem Typ löschen geben könnte ... aber in meiner Welt ist 'TypeReference' einfach zu benutzen und zu verstehen. – freedev