修复JsonMappingException:无法从Object值(token JsonToken.START_OBJECT)反序列化java.util.ArrayList的实例
最后更新:2024年5月11日
1. 概述
在本简短的教程中,我们将阐明如何修复异常JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (token `JsonToken.START_OBJECT`)。
首先,我们将突出显示异常的主要原因。然后我们将演示如何在实践中重现它,最后,如何解决它。
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: Can not deserialize instance of java.util.ArrayList from Object value (token `JsonToken.START_OBJECT`)的主要原因。然后我们展示了如何产生该异常以及如何解决它。
支持本文的代码可在 GitHub 上获取。 一旦你以 Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。















