2012-07-26 17 views
18

La cadena JSON es el siguienteparte de una cadena JSON usando Jackson

{ 
    "rank":"-text_relevance", 
    "match-expr":"(label 'star wars')", 
    "hits":{ 
     "found":7, 
     "start":0, 
     "hit":[ 
     {"id":"tt1185834", 
      "data":{ 
       "actor":["Abercrombie, Ian","Baker, Dee","Burton, Corey"], 
       "title":["Star Wars: The Clone Wars"] 
      } 
     }, 
     . 
     . 
     . 
     {"id":"tt0121766", 
      "data":{ 
       "actor":["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"], 
       "title":["Star Wars: Episode III - Revenge of the Sith"] 
      } 
     } 
     ] 
    }, 
    "info":{ 
     "rid":"b7c167f6c2da6d93531b9a7b314ad030b3a74803b4b7797edb905ba5a6a08", 
     "time-ms":2, 
     "cpu-time-ms":0 
    } 
    } 

Tiene muchos campos, pero sólo tengo que desee el campo Datos. Esto no funcionará:

mapper.readvalue(jsonString,Data.class); 

¿Cómo hago que Jackson lea solo el campo "Datos"?

Respuesta

14

Creo que la forma más fácil de hacerlo es usando Jackson TreeModel: deje que Jackson analice la entrada JSON en un objeto JsonNode que luego consulta, asumiendo cierto conocimiento de la estructura de datos. De esta manera puede ignorar la mayoría de los datos, caminando por el JsonNodes hasta la información que desee.

// String input = The JSON data from your question 
ObjectMapper mapper = new ObjectMapper(); 

JsonNode rootNode = mapper.readValue(input.getBytes(), JsonNode.class); 

// can also use ArrayNode here, but JsonNode allows us to get(index) line an array: 
JsonNode hits = rootNode.get("hits"); 

// can also use ObjectNodes here: 
JsonNode oneHit = null; 
JsonNode dataObj = null; 

int idx = 0; 

Data data = null; 


if (hits != null) 
{ 
    hits = hits.get("hit"); 

    if (hits != null) 
    { 
     while ((oneHit = hits.get(idx)) != null) 
     { 
      dataObj = oneHit.get("data"); 
      System.out.println("Data[" + idx + "]: " + dataObj); 
      idx++; 
     } 
    } 
} 

Salida:

Data[0]: {"id":"tt1185834","data":{"actor":["Abercrombie, Ian","Baker, Dee","Burton, Corey"],"title":["Star Wars: The Clone Wars"]}} 
Data[1]: {"id":"tt0121766","data":{"actor":["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"],"title":["Star Wars: Episode III - Revenge of the Sith"]}} 

puede seguir utilizando su implementación de la clase Data, pero creo que esto requerirá conseguir el String en representación de cada data - que el anterior depender de toString, o el uso de JsonNode.getText() - y volver -parsing utilizando el ObjectMapper:

mapper.readValue(dataArray, Data.class)); 

La alternativa es usar el Jackson Streaming Model e interceptar los nodos usted mismo hasta que vea la parte de la entrada que marca el comienzo de cada elemento data, luego consuma la cadena y llame al objectMapper.readValue en el contenido, para cada cadena.

+0

JsonNode rootNode = mapper.readTree (jsonString) –

22

Jackson 2.3 ahora tiene una clase JsonPointer que puede utilizar. Hay un ejemplo simple en su quick overview para el lanzamiento.

uso es simple: para JSON como

{ 
    "address" : { "street" : "2940 5th Ave", "zip" : 980021 }, 
    "dimensions" : [ 10.0, 20.0, 15.0 ] 
} 

podría utilizar expresiones como:

JsonNode root = mapper.readTree(src); 
    int zip =root.at("/address/zip").asIntValue(); 
    double height = root.add("/dimensions/1").asDoubleValue();// assuming it's the second number in there 
Cuestiones relacionadas