2013-03-06 18 views
11

Sto tentando di analizzare alcuni JSON (un esempio completo di JSON può essere visto in this Gist). Mostro la struttura generale del JSON qui sotto:Errore nell'utilizzo di Jackson e 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 
    } 
] 

Sto cercando di analizzare il JSON con le librerie di Jackson, ma ottengo il seguente errore durante il test:

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) 

Ecco il mio codice:

utente classe test: classe

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

utente:

0.123.516,410617 millions
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; 
    } 
} 

Qualcuno sa quale potrebbe essere il problema? Grazie.

+0

è possibile condividere il codice Java anche, è necessario convertire questo a un elenco –

+0

Come hai fatto a dichiarare la vostra proprietà 'authors'? Dovrebbe essere un tipo di raccolta o array. – Perception

+0

@Arun P Johny, ho modificato il documento e aggiunto il codice per vedere – tribrick

risposta

15

Due cose veloci:

  1. La classe utente sta definendo la proprietà authors come una stringa. Ma in JSON è un array, quindi è necessario utilizzare un tipo di collezioni o array nell'oggetto Java. Qualcosa di simile:

    private List<String> authors

  2. È ripetutamente analizzare il file JSON nella classe di test. Hai solo bisogno di analizzarlo una volta, e devi usare un token supertipo, dato che c'è un elenco di elementi nel JSON (non solo uno). Stai anche utilizzando il tipo sbagliato per deserializzare (User.class). Invece di tutte queste linee:

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

Basta usare:

Una volta ottenuto un elenco di utenti nella classe di test, è possibile eseguirne l'iterazione utilizzando un ciclo for enhanced.

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

è chiaro ma sto ricevendo questo errore ora: Eccezione nel thread "main" com.fasterxml.jackson.core.JsonParseException: End-of-input inatteso all'interno/tra le voci ARRAY in [Source : library.json; line: 11, column: 200] – tribrick

+0

@tribrick - scarica il contenuto del tuo file JSON in [jsonlint] (http://jsonlint.com) e verifica che sia ben formato. – Perception

+0

sì è un file JSON valido – tribrick

4

Dal momento che si sta lavorando con una serie, è necessario convertirlo in un array o un elenco

Come Array

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

come Lista

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

utente

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

Utilizzo:

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