2017-03-08 4 views
0

Ich bekomme einen Fehler beim Versuch, ein JSON-Array zu einer Liste von Objekten zu nehmen, die Ausnahme ist wie folgt.gson de-serialisieren Objekt-Array ohne Kennung

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 170 

hier ist der Code i

public static void main(String[] args) throws FileNotFoundException { 

    Gson gson = new Gson(); 

    Test test = new Test(); 

    JsonElement json = gson.fromJson(test.getFile("fieldTypes.json"), JsonElement.class); 
    String result = gson.toJson(json); 

    System.out.println(result); 

    Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType(); 

    JiraField[] jiraFields = gson.fromJson(result, listType); 

    for (JiraField jiraField : jiraFields) { 
     System.out.println(jiraField); 
    } 
} 

Dies ist der Inhalt der Datei

[ 
{ 
"id": "issuetype", 
"key": "issuetype", 
"name": "Issue Type", 
"custom": false, 
"orderable": true, 
"navigable": true, 
"searchable": true, 
"clauseNames": [ 
    "issuetype", 
    "type" 
], 
"schema": { 
    "type": "issuetype", 
    "system": "issuetype" 
} 
}, 
{ 
"id": "timespent", 
"key": "timespent", 
"name": "Time Spent", 
"custom": false, 
"orderable": false, 
"navigable": true, 
"searchable": false, 
"clauseNames": [ 
    "timespent" 
], 
"schema": { 
    "type": "number", 
    "system": "timespent" 
} 
} 
] 

Die Datei aus dem Ordner Ressourcen gelesen wird zu verwenden, versuche aber das funktioniert gut und Der SYSOUT zeigt den JSON-Inhalt korrekt an. Ich nehme an, dass es etwas gibt, was ich falsch mache?

+0

Da Sie versuchen, 'result' statt des echten Text-Datei in Ihrem zweiten Versuch zu lesen, könnte es sein, dass die' result' korrupt ist? Sie können auch sagen, in welcher Zeile der Fehler auftritt. –

+0

der Fehler im ersten Teil sagt BEGIN_ARRAY war aber BEGIN_OBJECT in Zeile 1 Spalte 170 – user2168435

Antwort

0

ok, so. stellt sich heraus, durch un zugeordneten Felder verursacht werden, das ist, wie ich es

in dem Objekt arbeiten haben Sie den @Expose Anmerkung für die Felder, die Sie

public class JiraField { 

@Expose 
private String id ; 
@Expose private String key ; 
@Expose private String name ; 
@Expose private boolean custom ; 
@Expose private boolean orderable ; 
@Expose private boolean navigable ; 
@Expose private String[] clauseNames ; 

Dann möchte hinzufügen, wenn Sie Gson initialisieren, was Sie tun es wie dieses

 Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 

dann funktioniert es :)

JiraFields{id='issuetype', key='issuetype', name='Issue Type', custom=false, orderable=true, navigable=true, clauseNames=[issuetype, type]} 
JiraFields{id='timespent', key='timespent', name='Time Spent', custom=false, orderable=false, navigable=true, clauseNames=[timespent]} 
0

Try this:

Type listType = new TypeToken<ArrayList<JiraField[]>>(){}.getType(); 

Ich denke, wir müssen das JiraField [] angeben, um Array zu erhalten.

+0

Dies würde auch nicht funktionieren: dieser Typ Token deklariert eine Array-Liste von Arrays von 'JiraField', daher ist es semantisch näher an' new TypeToken '. –

0

Ich nehme an, Sie haben eine verkleinerte JSON gemäß der Ausnahmebedingungsnachricht ...at line 1 column 170.... Es wäre schön, wenn Sie sowohl Ihr genaues JSON-Dokument als auch Ihr Mapping genau angeben würden, da das veröffentlichte JSON jetzt das Layout zerstört hat. Ich gehe davon aus auch Ihre Zuordnung ist Gewohnheit und im Grunde so etwas wie:

final class JiraField { 

    @SerializedName("id") 
    final String id = null; 

    @SerializedName("key") 
    final String key = null; 

    @SerializedName("name") 
    final String name = null; 

    @SerializedName("custom") 
    final boolean isCustom = Boolean.valueOf(false); 

    @SerializedName("orderable") 
    final boolean isOrderable = Boolean.valueOf(false); 

    @SerializedName("navigable") 
    final boolean isNavigable = Boolean.valueOf(false); 

    @SerializedName("searchable") 
    final boolean isSearchable = Boolean.valueOf(false); 

    @SerializedName("clauseNames") 
    final List<String> clauseNames = null; 

    @SerializedName("schema") 
    final List<String> schema = null; 

} 

Notiere die JiraField.schema Feldtyp: es ist eine Liste. Der Versuch, eine Liste von JiraField s mit der Standard-Konfiguration Gson in Folge hätte deserialisieren:

java.lang.IllegalStateException: Erwartet BEGIN_ARRAY wurde aber BEGIN_OBJECT in Zeile 1 Spalte 170 Pfade $ [0] .schema

Das Symptom und die Spalte sind genau die gleichen (aber wieder, ich bin nur assyming Ihre JSON-Datei wird minimiert), aber beachten Sie den Pfad $[0].schema Sie verpassten wahrscheinlich zu buchen: Es heißt, dass ein Array beginnen Token [ erwartet wird (da das Feld ist ein List<String>), aber war ein Objekt beginnen Token {. Das Ändern des Feldtyps in ein geeigneteres beliebiges Map<String, String> oder irgendein anderes benutzerdefiniertes POJO würde es beheben. Teilweise.

@SerializedName("schema") 
final Map<String, String> schema = null; 

Warum teilweise? Ihr Typ Token gebunden an ein ArrayList, aber Sie werfen das Deserialisierungsereignis Ergebnis auf ein Array JiraField[], daher können Sie so etwas wie dieses bekommen:

Exception in thread "main" java.lang.ClassCastException: java .util.ArrayList kann nicht in [LJiraField;

es zu beheben, müssen Sie Ihren jiraFields variable Anpassungs den deserialisiert Werttyp deklarieren: Es ist eine Array-Liste, aber kein Array - das ist nicht das gleiche in Java.

List<JiraField> jiraFields = ... 

Noch ein Hinweis in Bezug auf Deserialisierung ist, dass Sie nicht über ein Zwischen json Objekt müssen von deserialisieren. test.getFile höchstwahrscheinlich gibt java.io.Reader zurück, so dass Sie es direkt zur Deserialisierung übergeben können. Zusammenfassend alle auf, im Anschluss an die sollte für Sie arbeiten:

// Immutable and thread-safe, can be instantiated once and shared 
private static final Gson gson = new Gson(); 

// Immutable and thread-safe value type, the same story, + List instead of ArrayList - interfaces are usually much better 
private static final Type listType = new TypeToken<List<JiraField>>() { 
}.getType(); 

public static void main(final String... args) 
     throws IOException { 
    try (final Reader reader = test.getFile("fieldTypes.json")) { 
     final List<JiraField> jiraFields = gson.fromJson(reader, listType); 
     for (final JiraField jiraField : jiraFields) { 
      System.out.println(jiraField.key + " => " + jiraField.name); 
     } 
    } 
} 

Ausgang:

issuetype => Typ Ausgabe
timespent => Benötigte Zeit

0
Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType(); 

ArrayList<JiraField> jiraFields = gson.fromJson(result, listType); 

for (JiraField jiraField : jiraFields) { 
    System.out.println(jiraField); 
} 

Try Dieser Code

+0

Dies funktioniert auch nicht, zumindest als primäre Lösung. Das OP hatte Probleme mit unkorrektem Mapping, was dazu führte, dass JSON-Parsing andere Tokens erwartete, und das ist es, was die Ausnahme von OP sagt. Aber ja, das würde funktionieren, wenn OP-Mappings behoben sind. –

0

Kommentieren Sie diese Zeile

Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType(); 

Versuchen mit diesem

JiraField[] jiraFields = gson.fromJson(result, JiraField[].class); 
Verwandte Themen