2013-03-06 17 views
11

Ich versuche, einige JSON (vollständiges Beispiel des JSON in this Gist zu sehen) zu analysieren. Ich zeige die allgemeine Struktur des JSON unter:Fehler mit Jackson und Json

[ 
    { 
     "title": "Principles of Compiler Design", 
     "authors": [ 
      "Aho", 
      "Ullman" 
     ], 
     "publisher": "Addison Wesley", 
     "year": 1977 
    }, 
    { 
     "title": "Compilers: Principles Techniques and Tools", 
     "authors": [ 
      "Aho", 
      "Sethi", 
      "Ullman" 
     ], 
     "publisher": "Addison Wesley", 
     "year": 1985 
    } 
] 

Ich versuche, die JSON mit Jackson Bibliotheken zu analysieren, aber ich erhalte den folgenden Fehler während des Tests:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token 
at [Source: library.json; line: 2, column: 49] (through reference chain: com.acme.datatypes.User["authors"]) 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:163) 
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:588) 
    at com.fasterxml.jackson.databind.deser.std.JdkDeserializers$StringDeserializer.deserialize(JdkDeserializers.java:90) 
    at com.fasterxml.jackson.databind.deser.std.JdkDeserializers$StringDeserializer.deserialize(JdkDeserializers.java:59) 
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:336) 
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:89) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2563) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1759) 
    at com.acme.datatypes.UserTest.main(UserTest.java:20) 

Hier ist mein Code:

User Test Klasse:

public class UserTest { 
    public static void main(String[] args) throws JsonParseException, 
      JsonMappingException, IOException { 
     File jsonFile = new File("library.json"); 

     User user = null; 

     ObjectMapper mapper = new ObjectMapper(); 

     user = mapper.readValue(jsonFile, User.class); 
     System.out.println(user.getTitle()); 

     user = mapper.readValue(jsonFile, User.class); 
     System.out.println(user.getAuthors()); 

     user = mapper.readValue(jsonFile, User.class); 
     System.out.println(user.getPublisher()); 

     user = mapper.readValue(jsonFile, User.class); 
     System.out.println(user.getYear()); 
    } 
} 

Benutzerklasse:

public class User { 

    private String authors; 
    private String publisher; 
    private String title; 
    private Number year; 

    public String getAuthors() { 
     return this.authors; 
    } 

    public void setAuthors(String authors) { 
     this.authors = authors; 
    } 

    public String getPublisher() { 
     return this.publisher; 
    } 

    public void setPublisher(String publisher) { 
     this.publisher = publisher; 
    } 

    public String getTitle() { 
     return this.title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public Number getYear() { 
     return this.year; 
    } 

    public void setYear(Number year) { 
     this.year = year; 
    } 
} 

Weiß jemand, was das Problem sein könnte? Vielen Dank.

+0

können Sie den Java-Code auch gemeinsam nutzen, müssen Sie diese –

+0

in eine Liste konvertieren Wie haben Sie Ihre 'authors' Eigenschaft deklarieren? Es sollte eine Sammlung oder ein Array-Typ sein. – Perception

+0

@Arun P Johny, Ich habe das Dokument bearbeitet und fügte den Code für Sie zu sehen – tribrick

Antwort

15

Zwei schnelle Dinge:

  1. Ihre Benutzerklasse ist die Definition der authors Eigenschaft als String. Aber in JSON sein ein Array ist, so müssen Sie in Ihrem Java-Objekt eine Sammlung oder Array-Typen verwenden. Etwas wie:

    private List<String> authors

  2. Sie wiederholt die JSON-Datei in Ihrer Testklasse analysiert. Sie müssen es nur einmal analysieren, und Sie müssen ein Supertype-Token verwenden, da es eine Liste von Elementen in JSON gibt (nicht nur eine). Sie verwenden auch den falschen Typ zum Deserialisieren (User.class). Statt all diese Linien:

    user = mapper.readValue(jsonFile, User.class); System.out.println(user.getTitle());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getAuthors());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getPublisher());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getYear());

Verwenden Sie einfach:

List<User> userList = 
    mapper.readValue(jsonFile, new TypeReference<List<User>>() {}); 

Sobald Sie eine Liste der Benutzer in Ihrer Testklasse bekommen Sie iterieren sie eine for-Schleife verbessert werden.

for(User user : userList) { 
    System.out.println(user.getTitle()); 
} 
+1

Es ist klar, aber ich bekomme diesen Fehler jetzt: Ausnahme im Thread "Haupt" com.fasterxml.jackson.core.JsonParseException: Unerwartete Ende der Eingabe innerhalb/zwischen ARRAY Einträge bei [Quelle : library.json; line: 11, spalte: 200] – tribrick

+0

@tribrick - lade den Inhalt deiner JSON-Datei in [jsonlint] (http://jsonlint.com) und bestätige, dass sie wohlgeformt ist. – Perception

+0

ja es ist eine gültige JSON-Datei – tribrick

4

Da Sie mit einem Array arbeiten, müssen Sie es in ein Array oder eine Liste

Als Array

MyClass[] myObjects = mapper.readValue(json, MyClass[].class); 

Als

List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){}); 

Benutzer

public class User { 

    private List<String> authors; 
    private String publisher; 
    private String title; 
    private Number year; 

    public List<String> getAuthors() { 
     return this.authors; 
    } 

    public void setAuthors(List<String> authors) { 
     this.authors = authors; 
    } 

    public String getPublisher() { 
     return this.publisher; 
    } 

    public void setPublisher(String publisher) { 
     this.publisher = publisher; 
    } 

    public String getTitle() { 
     return this.title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public Number getYear() { 
     return this.year; 
    } 

    public void setYear(Number year) { 
     this.year = year; 
    } 
} 
Liste konvertieren

Verbrauch:

List<User> l = mapper.readValue(new File(""),new TypeReference<List<User>>() {}); 
Verwandte Themen