如何将这个JSON响应解析为POJO [英] How do I parse this JSON response into POJO

查看:107
本文介绍了如何将这个JSON响应解析为POJO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试班:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibm.cio.cloud.cost.model.ElasticResponse;
import com.jayway.jsonpath.JsonPath;

@JsonIgnoreProperties(ignoreUnknown = true)
public class TestJSONPaths {

    private static final String json = "{\"hits\":{\"total\":1,\"hits\":[{\"_id\":\"oEE4j2QBXCNPxFWHqq3i\",\"_score\":1.0,\"_source\":{\"status\":\"SUCCESSFUL\",\"reason\":\"OK, Single ACTIVE status can process\"}}]}}";

    public static void main(String[] args) {
        List<String> strippedJSON = JsonPath.read(json, "$.hits.hits._source");
        ElasticResponse response = null;
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);

        try {
            System.out.println("From this json string:" + strippedJSON + "\n");
            response = mapper.readValue(strippedJSON.toString(), ElasticResponse.class);
            System.out.println("ElasticDocument=" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(response.getDocuments()));
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这是ElasticResponse类的定义:

Here is the ElasticResponse class def:

public class ElasticResponse {
    private List<ElasticDocument> documents;
    public List<ElasticDocument> getDocuments() {
        return documents;
    }
    public void setDocuments(List<ElasticDocument> documents) {
        this.documents = documents;
    }
}

public class ElasticDocument {
    private String _id;

    private String status;
    private String reason;

   ... getters/setters
}

我正在尝试从给定的JSON映射一个ElasticDocument对象,但是它在下面抛出了以下错误.我正在尝试将JSON过滤掉,使其成为:[{__source document values}].此错误发生在Main类的第一行.我该如何映射这个Json?

I'm trying to get a ElasticDocument object mapped from the JSON given but it's throwing the following errors below. I'm attempting to filtered out the JSON to simply be: [{_source document values }]. This error occurs on the very first line in the Main class. How can I map this Json?

[DEBUG] Evaluating path: $['hits']['hits']['_source']
Exception in thread "main" com.jayway.jsonpath.PathNotFoundException: Expected to find an object with property ['_source'] in path $['hits']['hits'] but found 'net.minidev.json.JSONArray'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:71)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:62)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:53)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:61)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:502)
    at com.ibm.cio.cloud.cost.TestJSONPaths.main(TestJSONPaths.java:18)

推荐答案

该异常是由于jsonpath返回数组而不是对象,因此,如果您将jsonpath修复为以下形式:

The exception is due to the jsonpath returning an array instead of an object, so if you fix the jsonpath to look like this:

$.hits.hits[*]._source

然后它将正确评估.但是,这可能仍然无法实现您想要的功能.JsonPath.read()将为您反序列化JSON.但是您必须注意这一点:

Then it will evaluate properly. However, this probably still doesn't do what you want it to do.. The JsonPath.read() will deserialise the JSON for you. But you have to watch out with this:

public class Test {

    private static final String json = "{\"hits\":{\"total\":1,\"hits\":[{\"_id\":\"oEE4j2QBXCNPxFWHqq3i\",\"_score\":1.0,\"_source\":{\"status\":\"SUCCESSFUL\",\"reason\":\"OK, Single ACTIVE status can process\"}}]}}";


    public static void main(String[] args) {
        List<ElasticDocument> docs = JsonPath.read(json, "$.hits.hits[*]._source");

        System.out.println("elasticDoc: " + docs.get(0));
    }

    public static class ElasticDocument {
        public String _id;

        public String status;
        public String reason;

        @Override
        public String toString() {
            return "ElasticDocument{" +
                    "_id='" + _id + '\'' +
                    ", status='" + status + '\'' +
                    ", reason='" + reason + '\'' +
                    '}';
        }
    }
}

看起来像它一样工作,但是docs List现在实际上是MapList.显然可以在Jackson上注册JsonPath,但我无法使其工作

Looks like it works, however the docs List is now actually a List of Maps. Apparently It's possible to register JsonPath with Jackson but I can't make it work

或者,您可以使用Jackson来反序列化JSON,然后应创建与json结构匹配的对象模型,然后可以使用ObjectMapper进行反序列化

Alternatively you can use Jackson to deserialise the JSON, then you should create an object model that matches the json structure and then you can use the ObjectMapper to do the deserialisation

public class Test {

    private static final String json = "{\"hits\":{\"total\":1,\"hits\":[{\"_id\":\"oEE4j2QBXCNPxFWHqq3i\",\"_score\":1.0,\"_source\":{\"status\":\"SUCCESSFUL\",\"reason\":\"OK, Single ACTIVE status can process\"}}]}}";

    public static void main(String[] args) {

        System.out.println("From this json string:" + json + "\n");

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);

        try {

            HitsResource hitsResource = mapper.readValue(json, HitsResource.class);

            System.out.println("jackson elasticDoc: " + hitsResource.hitsParent.hits.get(0).source);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class HitsResource {
        @JsonProperty("hits")
        public HitsParent hitsParent;

        @Override
        public String toString() {
            return "HitsResource{" +
                    "hitsParent=" + hitsParent +
                    '}';
        }
    }

    public static class HitsParent {
        @JsonProperty("total")
        public Long total;
        @JsonProperty("hits")
        public List<Hits> hits;

        @Override
        public String toString() {
            return "HitsParent{" +
                    "total=" + total +
                    ", hits=" + hits +
                    '}';
        }
    }

    public static class Hits {
        @JsonProperty("_id")
        public String id;
        @JsonProperty("_score")
        public BigDecimal score;
        @JsonProperty("_source")
        public ElasticDocument source;

        @Override
        public String toString() {
            return "Hits{" +
                    "id='" + id + '\'' +
                    ", score=" + score +
                    ", source=" + source +
                    '}';
        }
    }

        public static class ElasticDocument {
            @JsonProperty("_id")
            public String _id;

            @JsonProperty("status")
            public String status;

            @JsonProperty("reason")
            public String reason;

            @Override
            public String toString() {
                return "ElasticDocument{" +
                        "_id='" + _id + '\'' +
                        ", status='" + status + '\'' +
                        ", reason='" + reason + '\'' +
                        '}';
            }
        }
}

这篇关于如何将这个JSON响应解析为POJO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆