简体   繁体   English

JSON String to Java String

[英]JSON String to Java String

I have these JSON String: 我有这些JSON字符串:

{
    "Results": {
        "output1": {
            "type": "table",
            "value": {
                "ColumnNames": ["userId", "documentId", "Scored Labels", "Scored Probabilities"],
                "ColumnTypes": ["String", "String", "Boolean", "Double"],
                "Values": [["100213199594809000000", "1Ktol-SWvAh8pnHG2O7HdPrfbEVZWX3Vf2YIPYXA_8gI", "False", "0.375048756599426"], ["103097844766994000000", "1jYsTPJH8gaIiATix9x34Ekcj31ifJMkPNb0RmxnuGxs", "True", "0.753859758377075"]]
            }
        }
    }
}

And I want to have only the ColumnNames and the Values . 我想只有ColumnNamesValues I have tried it with something like this: 我尝试过这样的事情:

Map<String,Object> map = mapper.readValue(filename, Map.class);
String CN = (String) map.get("ColumnNames");

But then I get the following error: 但后来我收到以下错误:

Exception in thread "main" org.codehaus.jackson.JsonParseException: Unexpected character ('A' (code 65)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
 at [Source: java.io.StringReader@64232b15; line: 1, column: 2]`

I've worked only few times with JSON. 我只用JSON工作了几次。 Can anybody help me here? 有人可以帮我吗?

The best case for me would be something like this, which I've done in another case: 对我来说最好的情况就是这样,我在另一个案例中做过:

String uId = (String) attr.get("userId");

Is it possible? 可能吗?

So now I've done this: 所以现在我做到了:

I try it like this: 我试试这样:

public class ClientPOJO {

    private String userId;
    private String documentId;


    public String getuserId() {
        return userId;
    }

    public void setuserId(String userId) {
        this.userId = userId;
    }

    public String getdocumentId() {
        return documentId;
    }

    public void setdocumentId(String documentId) {
        this.documentId = documentId;
    }

}

and then: 接着:

ObjectMapper mapper = new ObjectMapper();
                    ClientPOJO clientes= mapper.readValue(filename, ClientPOJO.class);

String uid = clientes.getuserId();

But now when I make a Prtinout I'll get the same error like before: 但是现在当我制作一个Prtinout时,我会像以前一样得到同样的错误:

    Exception in thread "main" org.codehaus.jackson.JsonParseException: Unexpected character ('A' (code 65)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
 at [Source: java.io.StringReader@7a6eb29d; line: 1, column: 2]

If you know exactly the structure of your json (like the json you have post) then you can using Gson to get your object like this: 如果你确切知道你的json的结构(就像你发布的json那样)那么你可以使用Gson来获取你的对象:

JsonParser parser = new JsonParser();
JsonObject json = (JsonObject) parser.parse("your_json_string_here");
String column = json.get("Results").getAsJsonObject().get("output1").getAsJsonObject().get("value").getAsJsonObject().get("ColumnNames").getAsJsonArray().toString();
String value = json.get("Results").getAsJsonObject().get("output1").getAsJsonObject().get("value").getAsJsonObject().get("Values").getAsJsonArray().toString();    
System.out.println(column);
System.out.println(value);

If you need some things more generic then you can parse your json string to a HashMap<String, Object> then using recursion to read the HashMap and get the value you want. 如果你需要更通用的东西,你可以将你的json字符串解析为HashMap<String, Object>然后使用递归来读取HashMap并获得你想要的值。 Example (in my code, the type of Map will corresponding to a Json Object, type of List will corresponding to the Array in Json string): 示例(在我的代码中,Map的类型将对应于Json对象,List的类型将对应于Json字符串中的Array):

Type type = new TypeToken<HashMap<String, Object>>() {}.getType();
Gson gson = new Gson();
HashMap<String, Object> map = gson.fromJson("your_json_string_here", type);
    for (String key : map.keySet()) {
        Object obj = map.get(key);
        if (obj instanceof List) {
            for (Object o : (List) obj) {
                if (o instanceof Map) {
                    loop((Map) o);
                } else {
                    System.out.println(key + " : " + o);
                }
            }
        } else if (obj instanceof Map) {
            loop((Map) obj);
        } else {
            System.out.println(key + " : " + obj);
        }
    }
}

private static void loop(Map<String, Object> map) {
    for (String key : map.keySet()) {
        Object obj = map.get(key);
        if (obj instanceof List) {
            for (Object o : (List) obj) {
                if (o instanceof Map) {
                    loop((Map) o);
                } else {
                    System.out.println(key + " : " + o);
                }
            }
        } else if (obj instanceof Map) {
            loop((Map) obj);
        } else {
            System.out.println(key + " : " + obj);
        }
    }
}

Neither Jackson nor any other library will parse the Values array into objects with client data like your POJO. Jackson和任何其他库都不会将Values数组解析为具有客户数据的对象,例如POJO。 You can achieve this by getting the raw tree of data in this JSON and constructing objects by iterating over the Values array inside this tree. 您可以通过在此JSON中获取原始数据树并通过迭代此树中的Values数组来构造对象来实现此目的。 Assuming the order of ColumnNames is fixed then you can parse with Jackson like this: 假设ColumnNames的顺序是固定的,那么您可以像这样解析Jackson:

final ObjectMapper mapper = new ObjectMapper();
final JsonNode tree = mapper.readTree(json);
final JsonNode values = tree.findValue("Values");

final List<ClientPOJO> clients = new ArrayList<>();
for (JsonNode node : values) {
    final ClientPOJO client = new ClientPOJO();
    client.setUserId(node.get(0).asText());
    client.setDocumentId(node.get(1).asText());
    client.setScoredLabels(node.get(2).asBoolean());
    client.setScoredProbabilities(node.get(3).asDouble());
    clients.add(client);
}

Docs for JsonNode . JsonNode的文档。 Basically with findValue you can get another node deep into the tree, with get you can get array elements by index and with asText etc you parse a value in JSON into the appropriate type in Java. 基本上与findValue你可以得到另一个节点深入树, get你可以通过索引与数组元素asText等你解析JSON中的值到Java中的相应类型。

Since you seem to be flexible in choice of JSON parsing library I would suggest Jackson 2 from com.fasterxml instead of Jackson 1 from org.codehaus that you tried. 由于您似乎可以灵活选择JSON解析库,我建议使用com.fasterxml Jackson 2而不是您尝试过的org.codehaus中的Jackson 1。

Below is an example to illustrate a generic approach to solve your problem ( based on Jackson library). 下面是一个示例,用于说明解决问题的一般方法(基于Jackson库)。 You may like to enhance the solution to meet your all requirements. 您可能希望增强解决方案以满足您的所有要求。

Comments inlined. 评论内联。

package com.stackoverflow;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

// Junit class
public class TableDeserExample {
    // sample input
    String inputJson = "{\n" +
            "    \"Results\": {\n" +
            "        \"output1\": {\n" +
            "            \"type\": \"table\",\n" +
            "            \"value\": {\n" +
            "                \"ColumnNames\": [\"userId\", \"documentId\", \"Scored Labels\", \"Scored Probabilities\"],\n" +
            "                \"ColumnTypes\": [\"String\", \"String\", \"Boolean\", \"Double\"],\n" +
            "                \"Values\": [[\"100213199594809000000\", \"1Ktol-SWvAh8pnHG2O7HdPrfbEVZWX3Vf2YIPYXA_8gI\", \"False\", \"0.375048756599426\"], [\"103097844766994000000\", \"1jYsTPJH8gaIiATix9x34Ekcj31ifJMkPNb0RmxnuGxs\", \"True\", \"0.753859758377075\"]]\n"
            +
            "            }\n" +
            "        }\n" +
            "    }\n" +
            "}";

    // POJO to map the Json structure. You may want to make it generalize based
    // on field "type"
    // (https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization)
    public static class Result {
        private String type;
        private TableResult value;

        public String getType() {
            return this.type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public void setValue(TableResult value) {
            this.value = value;
        }

        public TableResult getValue() {
            return this.value;
        }
    }

    // Pojo for table result
    public static class TableResult {
        private List<String> columnNames;
        private List<String> columnTypes;
        private List<Object[]> values;

        @JsonProperty("ColumnNames")
        public List<String> getColumnNames() {
            return this.columnNames;
        }

        public void setColumnNames(List<String> columnNames) {
            this.columnNames = columnNames;
        }

        @JsonProperty("ColumnTypes")
        public List<String> getColumnTypes() {
            return this.columnTypes;
        }

        public void setColumnTypes(List<String> columnTypes) {
            this.columnTypes = columnTypes;
        }

        @JsonProperty("Values")
        public List<Object[]> getValues() {
            return this.values;
        }

        public void setValues(List<Object[]> values) {
            this.values = values;
        }

    }

    // Top level Json POJO
    public static class ResultContainer {
        private Map<String, Result> results;

        @JsonProperty("Results")
        public Map<String, Result> getResults() {
            return this.results;
        }

        public void setResults(Map<String, Result> results) {
            this.results = results;
        }
    }

    // A contract to map the result "values" to the expected object
    public static interface ResultMapper<T> {
        T map(TableResult map, Object[] row);
    }

    // Basic implementation for mapping user object from json "values[i]" array
    public static class UserTableResultMapper implements ResultMapper<User> {

        @Override
        public User map(TableResult result, Object[] row) {
            User user = new User();
            // Here use any mapper logic based on column name
            // Retrieved from result object.
            // Below are for illustration only
            user.setId(String.valueOf(row[0]));
            user.setDocumentId(String.valueOf(row[1]));
            return user;
        }

    }

    // A result reader class
    public static class ResultReader<T> implements Iterable<T> {
        private TableResult result;
        private ResultMapper<T> mapper;

        public ResultReader(TableResult result, ResultMapper<T> mapper) {
            this.result = result;
            this.mapper = mapper;
        }

        @Override
        public Iterator<T> iterator() {
            final Iterator<Object[]> itr = result.getValues().iterator();
            return new Iterator<T>() {

                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }

                @Override
                public T next() {
                    Object[] values = itr.next();
                    return mapper.map(result, values);
                }

                @Override
                public boolean hasNext() {
                    return itr.hasNext();
                }
            };
        };
    }

    public static class User {
        private String id;
        private String documentId;
        // and others

        public String getId() {
            return this.id;
        }

        public void setDocumentId(String documentId) {
            this.documentId = documentId;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getDocumentId() {
            return this.documentId;
        }

    }

    @Test
    public void simpleTest() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        ResultContainer file = mapper.readValue(inputJson, ResultContainer.class);
        Result result = file.getResults().get("output1");
        ResultReader<User> userResultReader = new ResultReader<>(result.getValue(), new UserTableResultMapper());
        for (User user : userResultReader) {
            System.out.println(user.getId() + " : " + user.getDocumentId());
        }
    }
}

Java- Convert JSON string into string / integer / Object Java-将JSON字符串转换为字符串/整数/对象

String jsonString = "{"username":"Gajender"}";
org.json.JSONObject jsonObj =new JSONObject(jsonString);
String name = (String) jsonObj.get("username").toString();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM