RestTemplate - Jackson Deserializer

时间:2016-06-21 22:25:57

标签: jackson json-deserialization

我正在尝试使用RestTemplate来使用REST服务。我无法反序列化JSON响应。我使用自定义反序列化器,我的JSON有3个节点,但看起来只有一个到达反序列化器。以下是更多细节。

以下是响应JSON:

{
    "Hello": {
        "Hi": "Name1",
        "Call": "PhoneNumber1"
    },
    "Hello": {
        "Hi": "Name2",
        "Call": "PhoneNumber2"
    },
    "Hello": {
        "Hi": "Name3",
        "Call": "PhoneNumber3"
    }
}

我使用 @JsonDeserializer 在响应类中使用自定义反序列化器来获取属性Hello。

当我执行下面的readTree时:

JsonNode node = jp.getCodec().readTree(jp);

它到达deserialize方法,看起来它只有一个节点而不是3如下所示。有时它有第一个节点,有时是最后一个节点。这里可能出现什么问题?

提前感谢您查看此问题并提供帮助!

解答: 正如其他人提到的,这个JSON是无效的,因此Jackson无法对其进行反序列化。我必须以字符串形式获取响应,然后手动反序列化。

2 个答案:

答案 0 :(得分:1)

这很可能是因为这是无效的JSON,你不能拥有三个同名的节点。

或严格来说,这不是一个错误,但只有一个名为" Hello" 的项目将被计入as stated in this answer,这是不好的,因为json不保证对象中项目的顺序只是列表中项目的顺序。

如果你有可能改变响应,我会改为创建一个对象数组。

{ "Hello": [ { "Hi": "Name1", "Call": "PhoneNumber1" }, { "Hi": "Name2", "Call": "PhoneNumber2" }, { "Hi": "Name3", "Call": "PhoneNumber3" } ] } 然后你会得到一个JsonNode,它是一个可以迭代的JsonNodes数组。

答案 1 :(得分:1)

JsonNode是一个没有特定内容行为的超类。在您的示例中,您应该获得ObjectNode,但由于您的属性都具有相同的名称,因此只保留一个“Hello”属性。 readTree()是一种通用方法,如果可能,它会自动转换为您需要的返回类型。

如果你真的需要这个,你必须将你的JSON移动到数组结构:

// you will get one ArrayNode containing multiple ObjectNode
[
  {
    "Hello": {
      "Hi": "Name1",
      "Call": "PhoneNumber1"
    }
  },
  {
    "Hello": {
      "Hi": "Name2",
      "Call": "PhoneNumber2"
    }
  },
  {
    "Hello": {
      "Hi": "Name3",
      "Call": "PhoneNumber3"
    }
  }
]

// you will get one ObjectNode containing one property with an ArrayNode
{
  "Hello": [
    {
      "Hi": "Name1",
      "Call": "PhoneNumber1"
    },
    {
      "Hi": "Name2",
      "Call": "PhoneNumber2"
    },
    {
      "Hi": "Name3",
      "Call": "PhoneNumber3"
    }
  ]
}