首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我试图反序列化对象列表时,Jackson会抛出错误映射异常。

当我试图反序列化对象列表时,Jackson会抛出错误映射异常。
EN

Stack Overflow用户
提问于 2021-12-08 13:26:39
回答 1查看 336关注 0票数 1

我试图反序列化一个巨大的API有效负载。这个有效负载包含的字段比我需要的多得多,因此我正在使用@JsonIgnoreProperties(ignoreUnknown = true)。但是,在某个时候反序列化失败了,错误消息是:

代码语言:javascript
运行
复制
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of FIELD_NAME token
 at [Source: {
  "objectEntries": [
    {
      "objectKey": "KDS-4300"
    },
    {
      "objectKey": "KDS-4327"
    }
  ]
}; line: 2, column: 3]

我找到了那个案子的解决方案,建议使用

代码语言:javascript
运行
复制
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

我试过这个。但这没什么用。而且,我的结果数据不是单个值数组。它实际上包含两个值--因此解决方案无论如何都不会加起来。

下面是反序列化的目标类。

代码语言:javascript
运行
复制
@JsonIgnoreProperties(ignoreUnknown = true)
public class InsightQueryResult {
    @JsonProperty("objectEntries")
    private List<ObjectEntry> objectEntries;

    @JsonCreator
    public InsightQueryResult(List<ObjectEntry> objectEntries) {
        this.objectEntries = objectEntries;
    }

    public List<ObjectEntry> getObjectEntries() {
        return objectEntries;
    }

    // equals, hashCode and toString
}
代码语言:javascript
运行
复制
@JsonIgnoreProperties(ignoreUnknown = true)
public class ObjectEntry {
    @JsonProperty("objectKey")
    private String objectKey;

    @JsonCreator
    public ObjectEntry(String objectKey) {
        this.objectKey = objectKey;
    }

    public String getObjectKey() {
        return objectKey;
    }
 // equals, hashCode and toString
}

下面是我测试它的单元测试:

代码语言:javascript
运行
复制
    @Test
    public void shouldMapQueryResultToResultObject() throws IOException {
        final Resource expectedQueryResult= new ClassPathResource("testQueryPayload.json");
        final String expectedQueryResultData = new String(
                Files.readAllBytes(expectedQueryResult.getFile().toPath())).trim();

        final List<ObjectEntry> objectEntries = Arrays.asList(new ObjectEntry("KDS-4300"), new ObjectEntry("KD-4327"));
        final InsightQueryResult expectedQueryResult = new InsightQueryResult(objectEntries);

        final InsightQueryResult result = objectMapper.readValue(expectedQueryResultData, InsightQueryResult.class);

        assertThat(result).isEqualTo(expectedQueryResult);
    }

下面是我想反序列化的有效载荷

代码语言:javascript
运行
复制
// testQueryPayload.json
{
  "objectEntries": [
    {
      "objectKey": "KDS-4300"
    },
    {
      "objectKey": "KDS-4327"
    }
  ]
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-08 13:54:54

您应该简单地注释@JsonCreator的参数。

代码语言:javascript
运行
复制
@JsonCreator
public ObjectEntry(String objectKey) {
    this.objectKey = objectKey;
}

变成了

代码语言:javascript
运行
复制
@JsonCreator
public ObjectEntry(@JsonProperty(value = "objectKey", required = true) String objectKey) {
    this.objectKey = objectKey;
}

其他构造函数也是如此。

解释:

  • Serialization:--您有一个带有字段的实例,您用@JsonProperty("name") (或带有@JsonValue的getter )注释一个字段,这允许reflection.
  • Deserialization:按照相同的逻辑从您的实例中构建一个字符串json,当您用@JsonCreator注释一个构造函数时,您告诉杰克逊这是他们应该使用的构造函数来从Json字符串构建对象。但是,要么给他们一个空的构造函数(然后通过反射,他们以后会设置每个字段),要么告诉他们必须在每个构造函数参数中使用Json字符串的哪个字段。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70275800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档