杰克逊将单个项目反序列化为列表

时间:2016-02-04 12:27:46

标签: java json jackson

我正在尝试使用一个服务,该服务为我提供了一个具有字段的实体,它是一个数组。

{
  "id": "23233",
  "items": [
    {
      "name": "item 1"
    },
    {
      "name": "item 2"
    }
  ]
}

但是当数组包含单个项目时,将返回项目本身,而不是一个元素的数组。

{
  "id": "43567",
  "items": {
      "name": "item only"
    }
}

在这种情况下,Jackson无法转换为我的Java对象。

public class ResponseItem {

   private String id;
   private List<Item> items;

   //Getters and setters...
}

是否有直接的解决方案?

4 个答案:

答案 0 :(得分:16)

您不是第一个要求此问题的人。看起来很旧。

查看此问题后,您可以使用DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY

查看文档: http://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

您需要将此jackson功能添加到对象映射器。

我希望它会对你有所帮助。

答案 1 :(得分:4)

我认为注释更适合代码。

@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Item> items;

答案 2 :(得分:1)

可以使用自定义JsonDeserializer来解决此问题。

E.g。

class CustomDeserializer extends JsonDeserializer<List<Item>> {

    @Override
    public List<Item> deserialize(JsonParser jsonParser, DeserializationContext context)
            throws IOException, JsonProcessingException {

        JsonNode node = jsonParser.readValueAsTree();

        List<Item> items = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();

        if (node.size() == 1) {
            Item item = mapper.readValue(node.toString(), Item.class);
            items.add(item);

        } else {
            for (int i = 0; i < node.size(); i++) {
                Item item = mapper.readValue(node.get(i).toString(), Item.class);
                items.add(item);
            }
        }

        return items;
    }

}

你需要告诉jackson使用它来反序列化items,例如:

@JsonDeserialize(using = CustomDeserializer.class)
private List<Item> items;

之后它会起作用。快乐的编码:)

答案 3 :(得分:-2)

我很漂亮Gson能够在没有打嗝的情况下做到这一点。如果你坚持下去,希望有人可以帮助杰克逊。

(例如:https://stackoverflow.com/a/18547661/1638595

编辑:嘿,抱歉意思是说:&#34;希望有人可以帮助你......&#34;而不是&#34; can&#39;#34;显得很粗鲁。