2017-02-08 17 views
2

У меня есть пример вложенной объект JSON, как показано ниже:Джексон JSON Java вложен объект и массивы

{ 
"payload": { 
"id": "1", 
"apiResp": { 
    "apiRespDetails": { 
    "report": { 
     "reportId": "reportid1", 
     "reportDetails": [ 
     { 
      "code": "1", 
      "rating": "good" 
     }, 
     { 
      "code": "2", 
      "rating": "bad" 
     }, 
     { 
      "code": "3", 
      "rating": "fair" 
     } 
     ] 
    } 
    } 
    } 
} 
} 

мне нужен только объект отчета, мне не нужен какой-либо из его деталей родительского объекта. Какой был бы лучший способ получить именно это, используя Jackson API?

Я создал Java-класс под названием Report.java с полями reportId (String) и reportDetails (ListDetail), где ReportDetail - это еще один класс с кодом строковых полей, рейтингом и т. Д. Должен ли я использовать некоторый механизм Deserializer, JsonTreeParser ?Благодаря.

+0

вы можете просто создать соответствующие родительские объекты и только захватить то, что вы ищете – Coder

+0

Я не думаю, что он будет работать, как это. Мне нужно будет создать объект Java для каждого из вложенных объектов. Если есть 10 вложенных объектов, я не хочу добавлять сведения о них в свой класс. – NewQueries

+0

Вы можете захватить то, что ищете, с помощью '@ JsonProperty', и есть онлайн-реализации, которые генерируют все объекты Java, если вы просто вставляете свой JSON. Вы можете избавиться от объектов и элементов, которые вам не нужны. – Coder

ответ

1

Привет нашел два решения, используя Джексоном fasterxml API.

В первом вы можете просто использовать метод findValue на jsonNode и передать в строковом значении собственности/объект, который вы ищете

String jsonresponse = "above json string"; 
    JsonFactory jsonFactory = new JsonFactory(); 
    JsonParser jp = jsonFactory.createParser(jsonresponse); 
    jp.setCodec(new ObjectMapper()); 
    JsonNode jsonNode = jp.readValueAsTree(); 
    JsonNode reportNode = jsonNode.findValue("report");  
    ObjectMapper mapper = new ObjectMapper(); 
    Report report = mapper.convertValue(reportNode, Report.class); 

Это другое решение использовать JsonToken, который распространяется ответ JSon до вы найдете то, что вы ищете

JsonFactory factory = new JsonFactory();  
    factory.setCodec(new ObjectMapper()); 
    JsonParser parser = factory.createParser(jsonresponse); 
    while(!parser.isClosed()){ 
     JsonToken jsonToken = parser.nextToken(); 

     if(JsonToken.FIELD_NAME.equals(jsonToken)){ 
      String fieldName = parser.getCurrentName(); 
      if("report".equals(fieldName)) { 
       jsonToken = parser.nextToken(); 
       Report report = parser.readValueAs(Report.class);  
      } else { 
       jsonToken = parser.nextToken(); 
      } 
     } 
    } 
+0

очень хорошо. Вы устроили мне новые функции, где я думал, что все это знаю :) –

+0

рад, что это было полезно :) – NewQueries

1

Решение для этого jayway Java implementation for JsonPath.
JsonPath является эквивалентом json для языка запросов XPath для XML. запрос langauge довольно силен, как можно видеть в примерах на github readme.

Вот краткий демо, чтобы вы начали:

import java.io.*; 
import java.nio.charset.StandardCharsets; 
import java.nio.file.*; 
import com.jayway.jsonpath.*; 
import net.minidev.json.JSONArray; 
import static com.jayway.jsonpath.matchers.JsonPathMatchers.*; 

public class JsonPathDemo2 
{ 
    public static void main(String[] args) 
    { 
     // query: search for any report property below root 
     String jsonPathQuery = "$..report"; 

     try (InputStream is = Files.newInputStream(Paths.get("C://temp/xx.json"))) { 
      Object parsedContent = 
        Configuration.defaultConfiguration().jsonProvider().parse(is, StandardCharsets.UTF_8.name()); 
      System.out.println("hasJsonPath? " + hasJsonPath(jsonPathQuery).matches(parsedContent)); 
      Object obj = JsonPath.read(parsedContent, jsonPathQuery); 
      System.out.println("parsed object is of type " + obj.getClass()); 
      System.out.println("parsed object to-string " + obj); 
      JSONArray arr = (JSONArray)obj; 
      System.out.println("first array item is of type " + arr.get(0).getClass()); 
      System.out.println("first array item to-string " + arr.get(0)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

выход:

hasJsonPath? true 
parsed object is of type class net.minidev.json.JSONArray 
parsed object to-string [{"reportId":"reportid1","reportDetails":[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]}] 
first array item is of type class java.util.LinkedHashMap 
first array item to-string {reportId=reportid1, reportDetails=[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]} 
+0

Привет, спасибо за ваш ответ. Я искал что-то в джексон-апи. Я нашел ответ на это. Я поставлю решение здесь. Спасибо хоть. – NewQueries