jackson-dataformat-csv 不会忽略未知属性

mba*_*kas 4 csv kotlin jackson-dataformat-csv

尝试使用 jackson-dataformat-csv 解析 .csv 文件。文件包含许多与我的程序无关的列。

试图@JsonIgnoreProperties(ignoreUnknown = true)在我的数据类上使用and csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES),但都不起作用,并且应用程序抛出异常:

com.fasterxml.jackson.databind.RuntimeJsonMappingException: Too many entries: expected at most 2 (value #2 (17 chars) "policy_issue_date")
 at [Source: (com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader); line: 1, column: 37]

    at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:194)
    at pl.polins.readers.oc.OcPolicyCsvReader.readNext(OcPolicyCsvReader.kt:25)
    at pl.polins.readers.oc.OcPolicyCsvReaderTest.should read PolicyCsv from .csv file(OcPolicyCsvReaderTest.groovy:19)
Caused by: com.fasterxml.jackson.dataformat.csv.CsvMappingException: Too many entries: expected at most 2 (value #2 (17 chars) "policy_issue_date")
 at [Source: (com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader); line: 1, column: 37]
    at com.fasterxml.jackson.dataformat.csv.CsvMappingException.from(CsvMappingException.java:23)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._reportCsvMappingError(CsvParser.java:1210)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._handleExtraColumn(CsvParser.java:965)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._handleNextEntry(CsvParser.java:826)
    at com.fasterxml.jackson.dataformat.csv.CsvParser.nextToken(CsvParser.java:580)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:418)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1266)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:325)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:277)
    at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:192)
    ... 2 more
Run Code Online (Sandbox Code Playgroud)

是否有任何解决方案可以忽略 csv 中不需要的列?

mba*_*kas 9

找到解决方案:

csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)
Run Code Online (Sandbox Code Playgroud)


Cae*_*sar 5

这对我有用:

csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Run Code Online (Sandbox Code Playgroud)


Key*_*r00 5

介绍

为了便于理解,下面是一个简单的(Java)示例:

  1. 从 InputStream 读取 CSV 文件(jackson-dataformat-csv 依赖项)

  2. 将其内容映射到对象列表(jackson-core依赖项)

CSV 文件内容

假设是data.csv一个包含以下数据的 CSV 文件:

a;b;c
1;2;0.5
3;4;
Run Code Online (Sandbox Code Playgroud)

缺少属性的 Java 类数据

该类MyModel表示具有以下属性的数据类:

private Long a;
private Integer b;
Run Code Online (Sandbox Code Playgroud)

请注意,该属性c丢失,因此解析器将不得不忽略它。

读取 CSV 内容并映射到对象列表中

因此,CsvMapper可以与 Jackson 对象映射器结合使用,将记录从 CSV 文件读取到对象列表,整个过程以一种方便的方法进行:

<U> List<U> mapRecordsToObjects(InputStream inputStream, Class<U> encodingType) {
    CsvMapper csvMapper = new CsvMapper();
    CsvSchema bootstrapSchema = CsvSchema.emptySchema() //
                                         .withHeader() //
                                         .withColumnSeparator(";");
    ObjectReader reader = csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) //
                                   .readerFor(encodingType) //
                                   .with(bootstrapSchema);
    MappingIterator<U> iterator;
    try {
        iterator = reader.readValues(inputStream);
    } catch (IOException e) {
        throw new IllegalStateException(String.format("could not access file [%s]", this.source), e);
    }
    List<U> results = new ArrayList<>();
    iterator.forEachRemaining(results::add);
    return results;
}
Run Code Online (Sandbox Code Playgroud)

最后,我们来调用这个方法:

List<MyModel> result = mapRecordsToObjects(fileInputStream, MyModel.class);
Run Code Online (Sandbox Code Playgroud)

为了读取文件,您只需要初始化InputStream。

反序列化功能

文档中,该类DeserializationFeature有以下描述:

定义影响 Java 对象从 JSON 反序列化方式的简单开/关功能的枚举

在这个枚举类中,有许多具有默认状态的功能(有时默认启用,有时禁用)。该功能默认FAIL_ON_UNKOWN_PROPERTIES处于禁用状态,可以如示例所示启用。在其描述中,我们可以读到:

确定遇到未知属性(未映射到属性的属性,并且没有“任何 setter”或处理程序可以处理它)是否会导致失败(通过抛出 {@link JsonMappingException})的功能。