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

Jackson
Remote
1
08:30 PM · Nov 30 ,2025

1. 概述

在本簡短教程中,我們將闡明如何修復異常 JsonMappingException: 無法從 Object 值(令牌 `JsonToken.START_OBJECT`)中反序列化 java.util.ArrayList 實例

首先,我們將突出顯示異常的主要原因。然後,我們將演示如何在實踐中重現它,最後,我們將解決它。

2. 理解異常

通常,Jackson 會拋出 JsonMappingException 以指示在反序列化 JSON 字符串時發生的致命映射錯誤。因此,堆棧跟蹤 "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 失敗時會產生“Cannot deserialize value of type `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.