2013-03-06 21 views
11

Próbuję parsować niektóre JSON (pełny przykład JSON można zobaczyć w this Gist). Pokażę ogólną strukturę poniższej JSON:Błąd przy użyciu Jackson i 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 
    } 
] 

Próbuję analizować JSON z bibliotekami Jackson, ale pojawia się następujący błąd podczas testowania:

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) 

Oto mój kod:

Użytkownik klasa test: klasa

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()); 
    } 
} 

użytkownika:

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; 
    } 
} 

Czy ktoś wie, jaki może być problem? Dzięki.

+0

można udostępnić kod java również, trzeba przekonwertować to do listy –

+0

Jak deklarują swoją właściwość 'authors'? Powinien to być typ kolekcji lub tablica. – Perception

+0

@Arun P Johny, Edytowałem dokument i dodałem kod, aby zobaczyć – tribrick

Odpowiedz

15

Dwa szybkie rzeczy:

  1. Twoja klasa użytkownika jest określenie właściwości authors jako ciąg znaków. Ale w JSON jest to tablica, więc musisz użyć kolekcji lub typu tablicy w twoim obiekcie Java. Coś jak:

    private List<String> authors

  2. można wielokrotnie przetwarzać plik JSON w klasie testowej. Wystarczy przeanalizować go tylko raz i trzeba użyć tokenu nadtypu, ponieważ istnieje lista elementów w JSON (nie tylko jednym). Używasz także niewłaściwego typu do deserializacji (User.class). Zamiast tych wszystkich liniach:

    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());

Wystarczy użyć:

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

Po uzyskaniu listy użytkowników w klasie testowej można ją powtórzyć za pomocą ulepszonej pętli for.

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

jest jasne, ale otrzymuję teraz ten błąd: wyjątek w wątku "główny" com.fasterxml.jackson.core.JsonParseException: nieoczekiwany koniec wprowadzania w obrębie/między wpisami ARRAY w [Źródło : library.json; wiersz: 11, kolumna: 200] – tribrick

+0

@tribrick - zrzuć zawartość pliku JSON do [jsonlint] (http://jsonlint.com) i sprawdź, czy jest dobrze uformowany. – Perception

+0

yes to jest poprawny plik JSON – tribrick

4

Od pracy z tablicą, trzeba przekonwertować go do tablicy lub listy

Jak Array

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

Jak Lista

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

użytkownika

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; 
    } 
} 

Zastosowanie:

List<User> l = mapper.readValue(new File(""),new TypeReference<List<User>>() {}); 
Powiązane problemy