简体   繁体   English

使用Jackson嵌套Json到Map

[英]Nested Json to Map using Jackson

I'm trying to dynamically parse some JSON to a Map. 我正在尝试动态地将一些JSON解析为Map。 The following works well with simple JSON 以下适用于简单的JSON

        String easyString = "{\"name\":\"mkyong\", \"age\":\"29\"}";
    Map<String,String> map = new HashMap<String,String>();
    ObjectMapper mapper = new ObjectMapper();

    map = mapper.readValue(easyString, 
            new TypeReference<HashMap<String,String>>(){});

    System.out.println(map);

But fails when I try to use some more complex JSON with nested information. 但是当我尝试将一些更复杂的JSON与嵌套信息一起使用时失败了。 I'm trying to parse the sample data from json.org 我正在尝试解析json.org中的示例数据

{
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "GlossTerm": "Standard Generalized Markup Language",
          "Acronym": "SGML",
          "Abbrev": "ISO 8879:1986",
          "GlossDef": {
            "para": "A meta-markup language, used to create markup languages such as DocBook.",
            "GlossSeeAlso": [
              "GML",
              "XML"
            ]
          },
          "GlossSee": "markup"
        }
      }
    }
  }
}

I get the following error 我收到以下错误

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token 线程“main”中的异常com.fasterxml.jackson.databind.JsonMappingException:无法从START_OBJECT标记中反序列化java.lang.String的实例

Is there a way to parse complex JSON data into a map? 有没有办法将复杂的JSON数据解析成地图?

I think the error occurs because the minute Jackson encounters the { character, it treats the remaining content as a new object, not a string. 我认为错误的发生是因为杰克逊遇到{字符时,它将剩余内容视为新对象,而不是字符串。 Try Object as map value instead of String. 尝试将Object作为映射值而不是String。

public static void main(String[] args) throws IOException {

    Map<String,String> map = new HashMap<String,String>();
    ObjectMapper mapper = new ObjectMapper();

    map = mapper.readValue(x, new TypeReference<HashMap>(){});

    System.out.println(map);
}

output 产量

{glossary={title=example glossary, GlossDiv={title=S, GlossList={GlossEntry={ID=SGML, SortAs=SGML, GlossTerm=Standard Generalized Markup Language, Acronym=SGML, Abbrev=ISO 8879:1986, GlossDef={para=A meta-markup language, used to create markup languages such as DocBook., GlossSeeAlso=[GML, XML]}, GlossSee=markup}}}}}

Wrap your Map into a dumb object as container, like this: 将Map作为容器包装到一个哑对象中,如下所示:

public class Country {
  private final Map<String,Map<String,Set<String>>> citiesAndCounties=new HashMap<>;

  // Generate getters and setters and see the magic happen.
}

The rest is just working with your Object mapper, example Object mapper using Joda module: 其余的只是使用您的Object映射器,使用Joda模块的示例Object mapper:

public static final ObjectMapper JSON_MAPPER=new ObjectMapper().
          disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).
          setSerializationInclusion(JsonInclude.Include.NON_NULL).
          disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).
          registerModule(new JodaModule());

// Calling your Object mapper
JSON_MAPPER.writeValueAsString(new Country());

Hope that helps ;-) 希望有所帮助;-)

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

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