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

使用实例化的集合类型进行Jackson反序列化而不是初始化一个新类型?

宇文飞翮
2023-03-14

如果我有课

class DTO {
    final MySet<Types> values = MySetWrapper(EnumSet.of(Types.class));

    public MySet getValues() {
        return values;
    }
}

其中,MySet扩展了Set。杰克逊抱怨说

Cannot find a deserializer for non-concrete Collection type MySet

我理解,但我已经实例化了集合。我希望杰克逊在创建实例后为每个值调用add,类似于:

DTO o = new DTO();
MySet<Types> values = o.getValues();
for (Types type : jsonArray) {
    values.add(type );
}

我不希望它试图自己创建一个新的集合。

共有2个答案

姜楷
2023-03-14

使用JsonProperty找到答案:

@JsonProperty
private void setValues(Set<Types> types) {
    values.addAll(types);
}

谢天谢地,非常简短。

编辑:看起来你甚至不需要注释。

梁兴修
2023-03-14

该错误消息意味着DTO类被配置(默认或显式)以反序列化JSON输入的部分到DTO字段中的

Cannot find a deserializer for non-concrete Collection type MySet

如果您认为Jackson不应该直接在此字段上执行反序列化,您可以定义一个构造函数来设置值,并确保Jackson不会自动执行反序列化工作:为了实现这一点,请删除该字段的setter(或在其上添加@JsonIgnore)和任何将使用反射对字段进行反序列化的Jackson模块。

它将提供:

final MySet<Types> values = MySetWrapper(EnumSet.of(Types.class));

@JsonCreator
public MyFoo(Set<Types> values) { 
    this.values.addAll(values);
}

注意,我在构造函数集合中指定了,而不是MySet(由于接口不声明字段,所以不应该是问题),否则您会遇到同样的问题,因为您没有为MySet定义反序列化器<但是如果您为此实现反序列化器,您当然可以:

public MyFoo(MySet<Types> values) { 
    this.values.addAll(values);
}
 类似资料:
  • 我试图使用混合序列化集合,但Jackson不会保存类型信息。这是一个基本测试,说明会发生什么: 如何在第一个输出上实现输出?

  • 问题内容: 我有一个json字符串,应该将其反序列化为以下类 我该怎么做?这是通常的方式 但是我怎么提到T代表什么呢? 问题答案: 你需要为使用的每种通用类型创建一个对象,并将其用于反序列化。例如

  • 我有一个json字符串,我应该将其反序列化为以下类 我怎么做?这是通常的方式 但我怎么说T代表什么呢?

  • 序列化和反序列化的方式不同于 我已经创建了两个序列化程序 和 我用Jackson查看了序列化/反序列化映射 ,但找不到解决方案。

  • 问题内容: 我正在尝试制作一个使用Jackson来反序列化POJO的类。 看起来像这样… 我对此实施有2个问题。 首先是我将类类型传递给方法,以便对象映射器知道应反序列化的类型。有使用泛型的更好方法吗? 同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这看起来特别讨厌,因为我必须在此处强制转换T,然后还必须从调用它的方法中强制转换对象类型。 我在该项目中使用了Robo