4

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

试图@JsonIgnoreProperties(ignoreUnknown = true)在我的数据类和 上使用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

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

4

3 回答 3

10

找到解决方案:

csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)
于 2017-05-03T14:43:30.073 回答
5

这对我有用:

csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
于 2019-06-12T03:30:36.297 回答
3

介绍

为了便于理解,这里有一个简单的(Java)示例:

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

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

CSV 文件内容

让我们成为data.csv一个包含以下数据的 CSV 文件:

a;b;c
1;2;0.5
3;4;

缺少属性的 Java 类数据

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

private Long a;
private Integer b;

请注意缺少该属性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;
}

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

List<MyModel> result = mapRecordsToObjects(fileInputStream, MyModel.class);

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

反序列化功能

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

定义简单的开/关特性的枚举,这些特性会影响 Java 对象从 JSON 反序列化的方式

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

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

于 2020-05-20T13:39:39.927 回答