【问题标题】:Nested Json to Map using Jackson使用 Jackson 将 Json 嵌套到 Map
【发布时间】:2013-11-19 09:16:20
【问题描述】:

我正在尝试将一些 JSON 动态解析为 Map。以下内容适用于简单的 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);

但是当我尝试使用一些更复杂的 JSON 和嵌套信息时失败了。我正在尝试解析来自 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"
        }
      }
    }
  }
}

我收到以下错误

线程“main”com.fasterxml.jackson.databind.JsonMappingException 中的异常:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例

有没有办法将复杂的 JSON 数据解析成地图?

【问题讨论】:

  • 您想要一个简单的键/值映射的结果?您认为 JSON 数据将如何在这样的地图中表示?键和值是什么?
  • 我认为错误对象是因为杰克逊遇到 { 字符的那一刻,它将剩余的内容视为新对象,而不是字符串。您是否尝试过将地图定义为 HashMap
  • 詹姆斯不,我还没有尝试过。 Cyrille,我要做的是动态解析 JSON,而不必创建具有静态结构的对象。我正在处理的应用程序将接收 JSON,我不会提前知道架构是什么。理想情况下,我想做的是拥有某种包含 JSON 的映射,这样我就可以从上到下逐步遍历它,而无需提前了解它,并让用户选择他们想要撤回的数据。
  • @user2229544 我试过 HashMap ,它有效

标签: java json dictionary


【解决方案1】:

我认为错误的发生是因为杰克逊遇到 { 字符的那一刻,它将剩余的内容视为新对象,而不是字符串。尝试使用 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);
}

输出

{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}}}}}

【讨论】:

  • 太棒了!正是我想要的:)
【解决方案2】:

将您的地图包装成一个哑对象作为容器,如下所示:

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

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

其余的只是使用您的对象映射器,例如使用 Joda 模块的对象映射器:

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());

希望有帮助 ;-)

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 2016-02-02
    • 2015-06-03
    • 1970-01-01
    • 2017-08-29
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多