readvalue example deserializer deserialize array java json jackson deserialization pojo

java - example - objectmapper readvalue list



AsignaciĆ³n de datos JSON a Java Clase POJO con Jackson Mapper (1)

Estoy desarrollando una aplicación de Android y estoy tratando de implementar el procesamiento de algunos datos de Java utilizando las capacidades de Stream de Jackson. Para hacer esto, tengo algunos ejemplos de código para ejecutar y explicaré lo que cada uno hace a medida que avanzo.

Aquí está el JSON con el que estoy trabajando:

{ "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, }

El siguiente código es el POJO en el que se almacenarán estos datos a medida que recorre cada uno de los elementos de la lista de arreglos "usuarios" en mis datos:

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

Ahora el código de abajo esperaría ver los datos de JSON y luego tomar la lista de objetos de la matriz de "usuarios". Por ahora, quería simplemente imprimir el nombre de cada usuario en el LogCat para revisar que funciona y como se explicó anteriormente. Estoy buscando utilizar el método "" ya que los datos son bastante grandes y quiero evitar problemas de 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(); }

Sin embargo, el código anterior no funciona en su estado actual y recibo los siguientes errores 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)

Realmente agradecería cualquier ayuda que se pueda dar sobre esto ya que estoy atascado y no puedo seguir adelante.

Gracias por adelantado

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

Gracias por la respuesta y he intentado implementar el código, pero parece que todavía no funciona, el código que tengo ahora está a continuación:

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

¿Crees que tiene algo que ver con mi proceso que se ejecuta en una tarea ASYNC o que estoy accediendo a mi JSON a través de un servicio web? El error que obtengo está debajo junto con la línea que se muestra en:

Línea de error:

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

Código de error:

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

Espero que pueda ayudarme a resolver este último problema, gracias de nuevo por la asistencia.


No necesita la anotación @JsonRootName . Puedes simplemente leer el árbol y obtener la matriz de usuarios. A continuación, repita y use el readValue(JsonNode node, Class<T> class) ObjectMapper readValue(JsonNode node, Class<T> class) en cada nodo.

Tenga en cuenta que la ID en mayúscula en su json requiere una pista para el analizador sintáctico, de ahí la @JsonProperty(value="ID") en el 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; } }