1

如果我有课

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

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

4

2 回答 2

1

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

Cannot find a deserializer for non-concrete Collection type MySet

如果您认为 Jackson 不应该直接在该字段上执行反序列化,您可以定义一个构造函数来设置 values并确保 Jackson 不会自动执行反序列化工作:要实现它,删除该字段的 setter(或添加@JsonIgnore它) 以及任何将使用反射反序列化到字段的杰克逊模块。

它会给:

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

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

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

public MyFoo(MySet<Types> values) { 
    this.values.addAll(values);
}
于 2019-07-31T14:31:12.197 回答
0

使用以下方法找到答案@JsonProperty

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

谢天谢地,非常简短。

编辑:似乎您甚至不需要注释。

于 2019-07-31T18:51:30.377 回答