【问题标题】:Can't parse JSON array of arrays to LinkedHashMap in Jackson无法将 JSON 数组解析为 Jackson 中的 LinkedHashMap
【发布时间】:2013-03-12 16:05:56
【问题描述】:

我正在开发一个 Android REST 客户端。我们使用 JSON 作为数据交换格式,所以我使用 Jackson 解析器。我从服务器得到不同的 Json 响应,比如简单的数组:

{"user_id":"332","user_role":"1"} 

或者别的什么。我将所有这些内容解析为LinkedHashMap<String, Object>,一切正常,但是当我从服务器收到此响应时:

[ { "user_id":"352",
    "user_role":"expert",
    "name":"Test 12-18",
    "description":"Test" },

  { "user_id":"263",
    "user_role":"novice lab",
    "name":"Tom's Desk",
    "description":"Desk"}
]

解析后我得到了 null: {}。这是我使用 Jackson 的代码:

 ObjectMapper mapParametersToJSON = new ObjectMapper();
 String serverResponseBody = responseFromServer.getBody();
LinkedHashMap<String, Object> resultofOperation = new LinkedHashMap<String,
     Object>();
TypeReference<LinkedHashMap<String,Object>> genericTypeReferenceInformation = new
    TypeReference<LinkedHashMap<String,Object>>() {};
    try {
     resultofOperation =  mapParametersToJSON.readValue(serverResponseBody,
         genericTypeReferenceInformation);

那么,为什么杰克逊无法解析这个?我该如何解决这个问题?

【问题讨论】:

  • 为什么你不使用默认的 Json Parser Api?

标签: java android json jackson linkedhashmap


【解决方案1】:

其他人提出了这个问题,但解决方案有点不完整。如果需要处理 JSON 对象和数组,可以绑定到java.lang.Object,检查类型:

Object stuff = objectMapper.readValue(json, Object.class);

您将获得ListMap(具体而言,默认为ArrayListLinkedHashMap;这些默认值可以更改)。

或者你可以用JsonNode 做 JSON 树:

JsonNode root = objectMapper.readTree(json);
if (root.isObject()) { // JSON Object
} else if (root.isArray()) { ...
}

后者通常更方便。

一件好事是您仍然可以使用这些创建常规 POJO,例如:

if (root.isObject()) { MyObject ob = objectMapper.treeToValue(MyObject.class); } // 或者Object,使用objectMapper.convertValue(ob, MyObject.class)

所以你甚至可以对不同的类型进行不同的处理;来回不同的表示。

【讨论】:

    【解决方案2】:

    您问题中的第一个 JSON 是地图或对象。第二个是数组。您不是在解析数组,而是在解析地图。

    你需要做这样的事情:

    List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
    

    与答案here 几乎相同的问题。

    【讨论】:

    • 好的。但是有什么方法可以确定 JSON 类型:对象或数组,以便我可以使用一些 if/else 什么时候写 mapper.readvalue ?
    • 我没有在生产中使用过 Jackson,但似乎 JsonNode 有一个 isArray() 方法。我的理解是,当你使用映射器时,你通常知道你在映射什么;如果没有,您可能会使用 DOM。
    • 您也可以使用 Mapper 绑定到JsonNodeJsonNode root = mapper.readValueAsTree(source);
    • 很好,谢谢 StaxMan。反正一直想调查杰克逊。
    【解决方案3】:

    在 JSON 中,{"key": "value"} 是对象,["this", "that"] 是数组。

    因此,如果您收到对象数组,则应使用 List&lt;Map&lt;Key, Value&gt;&gt; 之类的内容。

    【讨论】:

      【解决方案4】:

      您正面临一个错误,因为[] 构造无法转换为Map 引用,只能在List 或数组中。

      我会建议这样做:

      ObjectMapper objectMapper = new ObjectMapper();
      
      List<Map<String,String>> parsedResult = objectMapper.reader(CollectionType.construct(LinkedList.class, MapType.construct(LinkedHashMap.class, SimpleType.construct(String.class), SimpleType.construct(String.class)))).readValue(serverResponseBody);
      
      //if you need the one result map
      Map<String, String> resultMap = new LinkedHashMap<String, String>();
      
      for (Map<String, String> map: parsedResult){
          resultMap.putAll(map);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多