知識庫 / JSON / Jackson RSS 訂閱

修復JsonMappingException:無法從Object值(JsonToken.START_OBJECT)中反序列化java.util.ArrayList實例

Jackson
HongKong
12
09:47 PM · Dec 05 ,2025

1. 概述

本教程將介紹如何解決異常 <em >JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (tokenJsonToken.START_OBJECT`)。

首先,我們將重點分析導致該異常的主要原因。然後,我們將演示如何在實踐中重現該異常,最後,我們將展示如何解決它。

2. 理解異常

通常,Jackson 在反序列化 JSON 字符串時會拋出 <em>JsonMappingException</em> 以指示致命的映射錯誤。因此,堆棧跟蹤“Can not deserialize instance of java.util.ArrayList”表明 Jackson 無法將 JSON 屬性映射到 ArrayList 實例。

簡而言之,導致此異常的最常見原因是在使用花括號 "…" 來表示集合,而不是方括號 "…"

3. 重新觸發異常

現在我們知道 Jackson 拋出 JsonMappingException 的原因,接下來讓我們通過一個實際示例來演示如何重現它。

讓我們考慮 Country 類:

public class Country {

    private String name;
    private List<String> cities;

    // standard getters and setters
}

如我們所見,一個國家由名稱和城市列表定義。

接下來,讓我們假定使用花括號來在 JSON 字符串中定義城市:

{
    "name": "Netherlands", 
    "cities": {"Amsterdam", "Tamassint"}
}

現在嘗試將 JSON 字符串反序列化為 Country 類型的對象,將會產生以下結果:

Cannot deserialize value of type `java.util.ArrayList<java.lang.String>` from Object value (token `JsonToken.START_OBJECT`)
at [Source: (String)"{"name":"Netherlands","cities":{"Amsterdam", "Tamassint"}}"; line: 1, column: 32] 
(through reference chain: com.baeldung.mappingexception.Country["cities"])
...

最後,我們將創建一個測試用例以確認這一點:

@Test
public final void givenJsonWithInvalidList_whenDeserializing_thenThrowException() throws JsonParseException, IOException {
    String json = "{\"name\":\"Netherlands\",\"cities\":{\"Amsterdam\", \"Tamassint\"}}";
    ObjectMapper mapper = new ObjectMapper();

    Exception exception = assertThrows(JsonMappingException.class, () -> mapper.reader()
      .forType(Country.class)
      .readValue(json));

    assertTrue(exception.getMessage()
      .contains("Cannot deserialize value of type `java.util.ArrayList<java.lang.String>`"));
}

如上所示,Jackson 失敗原因是出現了“無法反序列化 java.util.ArrayList<java.lang.String> 類型的值”。

主要原因是我們在使用花括號來表示城市列表。對於 Jackson,{"Amsterdam", "Tamassint"} 不是有效的 JSON 數組。

4.  修復異常

最簡單的方法是使用方括號而不是花括號來定義元素的集合。 因此,為了解決此異常,首先需要修復我們的JSON字符串:

{ 
    "name": "Netherlands",
    "cities": ["Amsterdam", "Tamassint"]
}

現在讓我們使用一個測試用例來驗證一切都按預期工作:

@Test
public final void givenJsonWithValidList_whenDeserializing_thenCorrect() throws JsonParseException, IOException {
    String json = "{\"name\":\"Netherlands\",\"cities\":[\"Amsterdam\", \"Tamassint\"]}";
    ObjectMapper mapper = new ObjectMapper();

    Country country = mapper.reader()
      .forType(Country.class)
      .readValue(json);

    assertEquals("Netherlands", country.getName());
    assertEquals(Arrays.asList("Amsterdam", "Tamassint"), country.getCities());
}

如我們所見,新的 JSON 字符串已成功地反序列化為 Country 對象。

5. 結論

在本文中,我們討論了導致JsonMappingException: 無法從 Object 值(token JsonToken.START_OBJECT)中反序列化 java.util.ArrayList 實例 的主要原因。 此外,我們展示瞭如何產生該異常以及如何解決它。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.