簡體   English   中英

Jackson 將單個項目反序列化為列表

[英]Jackson deserialize single item into list

我正在嘗試使用一個服務,該服務為我提供了一個實體,該實體的字段是一個數組。

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

有沒有直接的解決方案?

您不是第一個提出這個問題的人。 好像還挺舊的。

看完這個問題,可以使用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 功能添加到您的對象映射器中。

我希望它會幫助你。

我認為注釋更適合代碼。

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

可以使用自定義 JsonDeserializer 來解決此問題。

例如

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;

之后它將起作用。 快樂編碼:)

@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)似乎不適用於@JsonValue

這意味着如果您想將其中任何一個反序列化為列表,它將不起作用:

{
  "key": true
}
[
  {
    "key": true
  },
  {
    "key": false
  }
]

作為解決方案,可以像這樣創建自定義解串器:

@JsonDeserialize(using = CustomDeserializer.class)
public record ListHolder(List<Item> items) {}

public class CustomDeserializer extends JsonDeserializer<ListHolder> {

    @Override
    public LogRequest deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        List<Item> items;

        if (parser.isExpectedStartArrayToken()) {
            items = parser.readValueAs(new TypeReference<>() {});
        } else {
            items = List.of(parser.readValueAs(Item.class));
        }

        return new ListHolder(items);
    }
}

我很漂亮Gson能夠在沒有打嗝的情況下做到這一點。 希望有人可以幫助你,如果你堅持使用傑克遜。

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

編輯:嘿,對不起意思是說:“希望有人可以幫助你......”而不是“不能”。 顯得很粗魯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM