2013-09-06 12 views
5

Sto sviluppando un'applicazione Android e sto cercando di implementare l'elaborazione di alcuni dati Java utilizzando le funzionalità di streaming di Jackson. Per fare ciò, ho un esempio di codice da eseguire e spiegherò che cosa fa ognuno come vado.Mappatura di dati JSON su Java POJO Classe con Jackson Mapper

Ecco il JSON sto lavorando con:

{ 
"users": [ 
    { 
     "ID": "26", 
     "data1": "Momonth", 
     "data2": "2011-10-30 04:34:53" 
    }, 
    { 
     "ID": "45", 
     "data1": "Porto", 
     "data2": "2011-10-18 05:34:00" 
    }, 
    { 
     "ID": "21", 
     "data1": "Tomson", 
     "data2": "2011-10-12 02:44:13" 
    } 
], 
"success": 1, 
} 

Il codice qui sotto è il POJO in cui tali dati verranno memorizzati come un'iterazione ciascuna delle "utenti" voci di elenco matrice in miei dati:

@JsonRootName(value = "users") 
public class User { 

    String ID; 
    String data1; 
    String data2; 
    ... 

    public String getID() { 
     return ID; 
    } 
    public void setID(String iD) { 
     ID = iD; 
    } 
    public String getData1() { 
     return data1; 
    } 
    public void setData1(String data1) { 
     this.data1 = data1; 
    } 
    public String getData2() { 
     return data2; 
    } 
    public void setData2(String data2) { 
     this.data2 = data2; 
    } 
    ... 

} 

ora il codice qui sotto mi aspetterei a guardare i dati JSON e poi prendete la lista di array "utenti" di oggetti, io allora per ora voluto stampare semplicemente il nome di ciascun utente al LogCat di rivedere quel funziona e, come spiegato in precedenza, sto cercando di utilizzare il metodo "" come i dati abbastanza grande e voglio evitare problemi di memoria.

HttpRequest request = HttpRequest.get("http://www.site.com/android/app/getAllUsers.php"); 
final Reader reader = request.reader(); 
final ObjectMapper mapper = new ObjectMapper(); 
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); 
final JsonFactory factory = mapper.getFactory(); 

try { 

    JsonParser jp = factory.createParser(reader); 

    while(jp.nextToken() == JsonToken.START_OBJECT) { 

     String fieldName = jp.getCurrentName(); 

     jp.nextToken(); 

     final User a = mapper.readValue(jp.getText(), User.class); 

    } 
} catch (JsonParseException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
} catch (IOException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
} 

Tuttavia il codice di cui sopra non funziona nel suo stato attuale e ottengo i seguenti errori da Jackson:

09-06 11:11:25.326: W/System.err(15029): com.fasterxml.jackson.databind.JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'users'), but FIELD_NAME 
09-06 11:11:25.326: W/System.err(15029): at [Source: [email protected]; line: 1, column: 2] 
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.jackson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:2948) 
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2858) 
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1569) 
09-06 11:11:25.326: W/System.err(15029): at com.app.tool.UsersListActivity$LoadAllUsers.doInBackground(UsersListActivity.java:381) 
09-06 11:11:25.326: W/System.err(15029): at com.app.tool.UsersListActivity$LoadAllUsers.doInBackground(UsersListActivity.java:1) 
09-06 11:11:25.326: W/System.err(15029): at android.os.AsyncTask$2.call(AsyncTask.java:287) 
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
09-06 11:11:25.326: W/System.err(15029): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
09-06 11:11:25.326: W/System.err(15029): at java.lang.Thread.run(Thread.java:856) 

Vorrei davvero apprezzare tutto l'aiuto che può essere dato su questo come lo sono io bloccato e non può andare avanti.

Grazie in anticipo


** * ***EDIT* *** *** *


Grazie per la risposta e ho cercato di implementare il codice tuttavia ancora non sembra funzionare, il codice che ho ora è qui sotto:

protected String doInBackground(String... args) { 

    HttpRequest request = HttpRequest.get("http://www.site.com/android/app/getAllUsers.php"); 
    final Reader reader = request.reader(); 

    final ObjectMapper mapper = new ObjectMapper(); 
    final JsonFactory factory = mapper.getFactory(); 

    try { 

      JsonParser jp = factory.createParser(reader); 

      JsonNode root = mapper.readTree(jp); 
      ArrayNode users = (ArrayNode) root.path("users"); 

      Iterator<JsonNode> iterator = users.elements(); 

      while (iterator.hasNext()) { 
       User user = mapper.readValue(iterator.next(), User.class); 

       System.out.println("User Name = " + user.data1); 
      } 

     } catch (JsonParseException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

     return null; 
} 

pensi che abbia a che fare con la mia processo in esecuzione in un'attività ASYNC o che accedo al mio JSON tramite un servizio Web? L'errore che ottengo è al di sotto insieme alla linea che si vede su:

errore Linea: Codice

User user = mapper.readValue(iterator.next(), User.class); 

Errore:

The method readValue(JsonParser, Class<T>) in the type ObjectMapper is not applicable for the arguments (JsonNode, Class<User>) 

Speriamo che si può aiutarmi a risolvere questo ultimo numero fuori, grazie ancora per l'assistenza.

risposta

1

Non è necessaria l'annotazione @JsonRootName. Puoi solo leggere l'albero e ottenere la matrice degli utenti. Quindi scorrere e utilizzare readValue(JsonNode node, Class<T> class) su ciascun nodo.

Si noti che l'ID in maiuscolo nel proprio json richiede un suggerimento al parser, da cui l'annotazione @JsonProperty(value="ID") sul getter.

public class JacksonJSON { 

    public static void main(String[] args) throws Exception { 
     ObjectMapper mapper = new ObjectMapper(); 
     JsonNode root = mapper.readTree(JacksonJSON.class.getResourceAsStream("/users.json")); 
     ArrayNode users = (ArrayNode) root.path("users"); 

     Iterator<JsonNode> iterator = users.getElements(); 
     while (iterator.hasNext()) { 
      User user = mapper.readValue(iterator.next(), User.class); 

      System.out.println("User id=" + user.id + " data1=" + user.data1 + " data2=" + user.data2); 
     } 


    } 

} 


class User { 

    String id; 
    String data1; 
    String data2; 

    @JsonProperty(value="ID") 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getData1() { 
     return data1; 
    } 

    public void setData1(String data1) { 
     this.data1 = data1; 
    } 

    public String getData2() { 
     return data2; 
    } 

    public void setData2(String data2) { 
     this.data2 = data2; 
    } 

} 
+0

linea ho messo in Iterator iterator_traits = users.getElements(); Ottengo il seguente errore: Il metodo getElements() non è definito per il tipo ArrayNode – user723858

+0

Ho aggiornato la mia domanda con i dettagli sull'implementazione del tuo suggerimento, qualsiasi assistenza sarebbe ottima. Grazie – user723858

+0

@ user723858 - quale versione di jackson stai usando? Ho provato con 1.9.9 – Qwerky

Problemi correlati