java - 如何使用 Jackson 从 JSON 文件加载多个 HashMap

标签 java json hashmap jackson

基本上我正在使用编写一个 JSON 文件

private void setupDictionaries() {
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode arrayNode = mapper.createArrayNode();
    JsonNode rootNode = mapper.createObjectNode();
    ArrayList<String> myThing = new ArrayList<String>();
    myThing.add("hi");
    myThing.add(".");

    itemsDict.put("cake", myThing);

    JsonNode childNode1 = mapper.valueToTree(itemsDict);
    ((ObjectNode) rootNode).set("Jan",  childNode1);
    JsonNode childNode2 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj2", childNode2);
    JsonNode childNode3 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj3", childNode3);
    String jsonString;
    try {
        jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
        System.out.println(jsonString);
        ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());
        writer.writeValue(new File(statsFile), jsonString);
    } catch (JsonProcessingException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

在此 JSON 文件中,我希望为所有 12 个月生成一个类似的字典,并仅加载我想要专门使用的字典。但是,由于这些不是简单的 HashMap,因此当我尝试加载 json 文件时,会出现异常。加载代码:

private HashMap<String, List<String>> loadDict() {
    ObjectMapper mapper = new ObjectMapper();
    try {
        HashMap<String, ArrayList<String>> map = mapper.readValue(new File(statsFile), new TypeReference<HashMap<String, ArrayList<String>>>() {});
        //Object map = mapper.readValue(new File(statsFile), new TypeReference<Object>() {});
        System.out.println(map.get("cake");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

异常(exception):

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.HashMap: no String-argument constructor/factory method to deserialize from String value

我的 JSON 文件:

{ "Jan" : { "cake" : [ "hi", "." ] }, "obj2" : { }, "obj3" : { } }

编辑:我想我找到了导致它的原因

String input = new String(Files.readAllBytes(Paths.get(statsFile)));
        System.out.println(input);
        String input1 = "{\r\n  \"Jan\" : {\r\n    \"cake\" : [ \"hi\", \".\" ]\r\n  },\r\n  \"obj2\" : { },\r\n  \"obj3\" : { }\r\n}";
        System.out.println(input1);

运行这段代码,输入是:

"{\r\n \"Jan\" : {\r\n \"cake\" : [ \"hi\", \".\" ]\r\n },\r\n >\"obj2\" : { },\r\n \"obj3\" : { }\r\n}" { "Jan" : { "cake" : [ "hi", "." ] }, "obj2" : { }, "obj3" : { } } (basically reading from a file, all of it is on a single line, where as having the actual json string in an input string its nice and clean, broken up into multiple lines) Now I only need to figure out how to overcome this...

已解决 我必须写入 rootNode,而不是将 jsonString 写入文件

private void setupDictionaries() {
    ObjectMapper mapper = new ObjectMapper();
    ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());

    ArrayNode arrayNode = mapper.createArrayNode();
    JsonNode rootNode = mapper.createObjectNode();
    ArrayList<String> myThing = new ArrayList<String>();
    myThing.add("hi");
    myThing.add(".");

    itemsDict.put("cake", myThing);

    JsonNode childNode1 = mapper.valueToTree(itemsDict);
    ((ObjectNode) rootNode).set("Jan",  childNode1);
    JsonNode childNode2 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj2", childNode2);
    JsonNode childNode3 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj3", childNode3);
    String jsonString;
    try {
        //jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
        System.out.println(rootNode);
        writer.writeValue(new File(statsFile), rootNode);
    } catch (JsonProcessingException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

我可以简单地查询

private HashMap<String, List<String>> loadDict() {
    ObjectMapper mapper = new ObjectMapper();
    try {
        System.out.println("...");
        HashMap<String, HashMap<String, ArrayList<String>>> map = mapper.readValue(new File(statsFile), new TypeReference<HashMap<String, HashMap<String, ArrayList<String>>>>() {});
        System.out.println(map.get("Jan").get("cake").get(0));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

谢谢大家

最佳答案

问题出在你的 TypeReference 上。您的示例 JSON 类似于 HashMap<String, HashMap<String, ArrayList<String>>>

对于HashMap<String, ArrayList<String>> JSON 应该类似于

{ "Jan" : [ "hi", "." ] , "obj2" : [ ], "obj3" : [ ] }

更新:

测试示例 JSON:

public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
    String input = "{ \"Jan\" : { \"cake\" : [ \"hi\", \".\" ] }, \"obj2\" : { }, \"obj3\" : { } }";
    ObjectMapper mapper = new ObjectMapper();
    HashMap<String, HashMap<String, ArrayList<String>>> map = mapper.readValue(input,
            new TypeReference<HashMap<String, HashMap<String, ArrayList<String>>>>() {
            });
    System.out.println(map.get("Jan").get("cake").get(0));

}

关于java - 如何使用 Jackson 从 JSON 文件加载多个 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42725271/

相关文章:

java - GWT - MVP 事件总线。创建多个处理程序

php - 使用 xmlhttp.responseText 中的 JSON 解析数组

java - 空点异常 - ImageLoader

java - Java中根据变量选择数组

hashmap - 使用新的但相同值的键通过对象键访问 Haxe map

java - Eclipse生成的hashCode函数好用吗?

java - 使用 Netbeans 6.5 GUI Builder 创建 JButton 数组

java - Spring JDBC中的独立事务

java - 在java中通过UDP传输文件

json - Go Unmarshal json,其键可以是两种类型之一