当前位置: 首页 > 知识库问答 >
问题:

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

施晗日
2023-03-14

我尝试反序列化一个巨大的API负载。这个有效负载包含的字段比我需要的要多,因此我正在使用@JsonIgnoreProperties(ignoreUnknown=true)。但是,在某些情况下,反序列化会失败,并显示错误消息:

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]

我找到了解决方案,建议使用

objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

我试过这个。但这于事无补。此外,我的结果数据不是一个单一的值数组。它实际上包含两个值——因此解决方案无论如何都不会相加。

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

@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
}
@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
}

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


    @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);
    }

这是我想要反序列化的有效负载

// testQueryPayload.json
{
  "objectEntries": [
    {
      "objectKey": "KDS-4300"
    },
    {
      "objectKey": "KDS-4327"
    }
  ]
}

共有1个答案

鄢开诚
2023-03-14

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

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

变成了

@JsonCreator
public ObjectEntry(@JsonProperty(value = "objectKey", required = true) String objectKey) {
    this.objectKey = objectKey;
}

另一个构造函数也是如此。

说明:

  • 序列化:您有一个带有字段的实例,您用@JsonProperty(“name”)注释一个字段(或者用@JsonValue注释getter),这允许Jackson通过反射从您的实例构建字符串json。
  • 反序列化:遵循相同的逻辑,当您使用@JsonCreator注释构造函数时,您告诉Jackson这是他们应该使用的构造函数,用于从他们拥有的Json字符串构建对象。但是,您要么给他们一个空构造函数(然后通过反射,他们稍后将设置每个字段),要么您必须告诉他们在每个构造函数参数中必须使用Json字符串的哪个字段
 类似资料:
  • 我对Jackson有一个错误的理解,就是将json文件反序列化为poco。这是我的代码: 我的POCO命名为AnimalBean: }还有我的JSON文件: } 当我执行我的代码时,我有以下错误:未识别的字段“动物园”(类动画豆),未标记为可忽略的。我知道问题是我的json文件开始不直接由动物,但我不能改变它,因为它不是我的。我已经尝试把对象apper.configure(Deseriazatio

  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)

  • 我有一个抽象的超类A,我有几个具体的子类B,C,D 在序列化方面,我执行以下操作: 没问题。我现在想反序列化这个。我知道我不能实例化一个抽象类,那么这是如何实现的呢? 这不起作用: 编辑:我把这个添加到我的抽象超类中:(仍然没有运气) 再次编辑:我现在遇到以下错误: 看看JSON,@class不在那里。我怎样才能做到?我试过: 但这并没有奏效。有这方面的例子吗?如何告诉对象映射器对类使用我的注释?

  • 我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢

  • 我有以下控制器: 使用以下请求对象: 当帖子通过并查看我得到的对象时,有效负载列表中有LinkedHashMap对象,而不是我的DTO类型的对象。 如何让Spring jackson将JSON转换为我的DTO对象。请记住,我计划对其他对象列表重用包装器响应DTO,这就是我使用通用列表(List)的原因。 这是我正在尝试的JSON。