La cartographie des données JSON à Java Classe POJO avec Jackson Mappeur
Je développe une application android et je suis en train de mettre en œuvre le traitement de certaines données Java en utilisant les fonctionnalités de Flux de Jackson. Pour ce faire, j'ai quelques exemple de code pour courir à travers et vous expliquera ce que chacun fait comme je l'aller.
Voici le JSON, je travaille avec:
{
"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,
}
Le code ci-dessous est le POJO où ces données sont stockées comme il parcourt chacun des "utilisateurs" tableau des éléments de liste dans mes données:
@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;
}
...
}
Maintenant le code ci-dessous je m'attends à regarder les données JSON et puis, prenez les "usagers" de la liste des ensembles d'objets, j'ai donc pour l'instant voulais simplement imprimer le nom de chaque utilisateur pour le LogCat pour examiner que cela fonctionne et comme expliqué précédemment, je suis à la recherche d'utiliser la "méthode" que les données est assez grand et je veux éviter des problèmes de mémoire.
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();
}
Cependant le code ci-dessus ne fonctionne pas dans son état actuel et j'obtiens l'erreur suivante de 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: java.io.InputStreamReader@432b1580; 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)
Je voudrais vraiment apprécier l'aide que peut être donnée sur ce que je suis coincé et ne peut pas aller de l'avant.
Merci d'avance
******MODIFIER********
Merci pour la réponse et j'ai essayé de mettre en œuvre le code cependant il ne semble pas encore fonctionner, le code que j'ai maintenant est ci-dessous:
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;
}
Vous pensez que ça n'a rien à voir avec mon processus en cours d'exécution dans une tâche ASYNCHRONE ou que j'accède à mon JSON via un service web? L'erreur que j'obtiens est ci-dessous avec la ligne qu'il montre sur:
Ligne D'Erreur:
User user = mapper.readValue(iterator.next(), User.class);
Code D'Erreur:
The method readValue(JsonParser, Class<T>) in the type ObjectMapper is not applicable for the arguments (JsonNode, Class<User>)
J'espère que vous pouvez m'aider à régler ce dernier problème, merci encore pour l'aide.
OriginalL'auteur user723858 | 2013-09-06
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas besoin de la
@JsonRootName
annotation. Vous pouvez seulement lire l'arbre et obtenir les utilisateurs de tableau. Alors parcourir et utiliserObjectMapper
'sreadValue(JsonNode node, Class<T> class)
sur chaque nœud.Noter que le capitalisés ID dans votre json nécessite une allusion à l'analyseur, d'où le
@JsonProperty(value="ID")
annotation sur le getter.J'ai mis à jour ma question avec plus de détails sur la mise en œuvre de votre suggestion, toute aide serait super. Merci
quelle est la version de jackson utilisez-vous? J'ai testé avec 1.9.9
Je suis l'aide de la dernière version
Par souci de complétude, readValue reçoit un JsonParser. La réponse ci-dessus fonctionne si vous modifiez readValue(iterator.next(), User.class) pour readValue(iterator.next().traverse(), User.class)
OriginalL'auteur Qwerky