Jackson JSON Java вложенные объекты и массивы



У меня есть пример вложенного объекта json, как показано ниже:



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


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



Я создал класс Java под названием Report.java с полями reportId (строка) и reportDetails (список ReportDetail), где ReportDetail-это другой класс со строковым кодом полей, рейтингом и т. д. Нужно ли мне использовать какой-то десериализатор, JsonTreeParser механизм?Спасибо.

1025   2  

2 ответов:

Решением для этого являетсяреализация Java jayway для JsonPath .
JsonPath является эквивалентом json для языка запросов XPath для XML. язык запросов довольно мощный, как видно из примеров на 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"}]}

Hi нашел два решения, используя jackson 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();
            }
        }
    } 

Comments

    Ничего не найдено.