【问题标题】:Hashmap unrecognized by CsvMapperHashmap 无法被 CsvMapper 识别
【发布时间】:2019-07-23 20:00:57
【问题描述】:

我正在尝试序列化一个包含 HashMap 的对象,但出现以下异常。

com.fasterxml.jackson.dataformat.csv.CsvMappingException: Unrecognized column 'tags': known columns: ["_id","insertDate"] (through reference chain.

另外,我不明白为什么在涉及序列化时需要有一个模式。在我看来,没有办法有一个无法识别的字段,因为它都是在类中指定的。

因为我不太了解杰克逊,所以我搜索并尝试了这两个注释的各种组合。 @JsonUnwrapped@JsonAnyGetter

class Product{
    public @Id String _id;

    @JsonUnwrapped
    private HashMap<String, String> tags = new HashMap<>();

    public String insertDate;

    @JsonAnyGetter
    public HashMap<String, String> getTags() {
        return tags;
    }
    @JsonAnySetter
    public void setTags(HashMap<String, String> tags) {
        this.tags = tags;
    }
}

用于序列化的代码

CsvSchema schema = csvMapper.schemaFor(Product.class).withHeader();
ObjectWriter myObjectWriter = csvMapper.writer(schema);
csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE);
csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
string = myObjectWriter.writeValueAsString(someProduct);

试试 NR 2

public class Product {

public @Id String _id;

public Map<String, String> tags = new HashMap<>();

public String insertDate;

@JsonAnyGetter
public Map<String, String> getTags() {
    return tags;
}
@JsonAnySetter
public void setTags(Map<String, String> tags) {
    this.tags = tags;
}

}

新错误

com.fasterxml.jackson.dataformat.csv.CsvMappingException: CSV generator does not support Object values for properties (nested Objects) (through reference chain: main.model.Product["tags"])

【问题讨论】:

  • 我们可以看看你的 json 吗?
  • @Coder 没有 json。我创建了一个 Product 类型的对象并尝试以 csv 序列化形式获取它。

标签: java jackson jackson-dataformat-csv


【解决方案1】:

Collection 实现类HashMap&lt;String, String&gt; 用于字段type(而不仅仅是其初始值type)让Jackson 感到困惑。

Jackson 检查接口java.util.Map 以选择适当的序列化器,如

的构造函数所示

com.fasterxml.jackson.databind.ser.std.MapSerializer

根据架构问题,根据 jackson-dataformat-csv文档

需要注意的是,需要架构对象来确保 列的正确排序;

还要注意,虽然显式类型可以提高效率,但通常 不需要,因为杰克逊数据绑定可以做常见的 转换/强制

我猜ObjectWriter.writeValueAsString(Object) 可以反身检查以推断序列化对象的类型。

由于 CSV 格式的表格性质,不能很好地支持深度嵌套的数据结构。

@JsonUnwrapped 仅用于(嵌套的)POJO-s。你想要的是使用@JsonAnyGetter。它需要返回java.util.Map。 JavaDocs:

注意,注解方法的返回类型必须是Map)。

如果您只是序列化,则不需要@JsonAnySetter

我很好奇你为什么使用 Map 作为标签。也许List&lt;String&gt; tags 就足够了,标签只有名字。

值得一试:https://www.baeldung.com/jackson-mapping-dynamic-object

【讨论】:

  • 我已经尝试了您的答案,但现在又遇到了另一个错误。也许我没听懂你。请查看更新后的问题,谢谢。
  • 您可以通过手动创建自己的模式来完成此操作,而不是使用 Pojo.class 生成的模式。将关键字段添加为列,然后在地图上使用 @AnyGetter。
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2016-07-20
  • 1970-01-01
相关资源
最近更新 更多