如何正确反序列化由包含另一个对象的列表项组成的 json?

Posted

技术标签:

【中文标题】如何正确反序列化由包含另一个对象的列表项组成的 json?【英文标题】:How do I correctly deserialize json that consists of a list item that includes another object? 【发布时间】:2022-01-02 23:10:19 【问题描述】:

我使用的客户端返回 json 格式如下:

[
    
        "source": "ANY"
    
]

即对象所在数组的元素。

我正在尝试提出这样的请求:

restTemplate.postForObject<AbcdResponse>(
    "/address",
    listOf(value).let  JsonHttpEntity(it) 
)
data class AbcdResponse(
    val obj: AbcdObject
)
data class DaDataAddress(
    val source: String?
)

但我得到了HttpMessageNotReadableException 异常:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token
 at [Source: (ByteArrayInputStream); line: 1, column: 1]

如何正确反序列化响应?

【问题讨论】:

【参考方案1】:

您可能已经注意到,响应作为一个整体是一个 JSON 数组。您可以通过包围整个内容的方括号[ ... ] 来判断。

因此,您无法将其反序列化为对象(例如AbcdResponse)。你应该做的是使用List&lt;DaDataAddress&gt; 而不是AbcdResponse

【讨论】:

【参考方案2】:

你真的不需要AbcdResponse。您需要在调用服务时使用ParameterizedTypeReference,如下所示:

restTemplate.exchange("/address", 
    HttpMethod.POST, 
    listOf(value).let  JsonHttpEntity(it) , 
    ParameterizedTypeReference<List<DaDataAddress>>() )

原因是您正在调用的服务正在返回 JSON 对象的 JSON 数组。

【讨论】:

以上是关于如何正确反序列化由包含另一个对象的列表项组成的 json?的主要内容,如果未能解决你的问题,请参考以下文章

反序列化时如何正确测试数据类型

如何让 ServiceStack 序列化/反序列化具有正确类型的 expando 对象

如何将 xml 对象反序列化回类列表

基于来自 JSON 请求主体的另一个属性,反序列化来自 JSON 请求主体的抽象属性

Java - 如何反序列化带有嵌套对象和列表的 JSON 数组? [复制]

包含对象列表的 SnakeYaml 反序列化类