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

时间:2017-05-03 12:45:38

标签: csv kotlin jackson-dataformat-csv

尝试使用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中不需要的列?

3 个答案:

答案 0 :(得分:3)

找到解决方案:

csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)

答案 1 :(得分:1)

简介

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

  1. 从InputStream中读取CSV文件({{1} 依赖性)

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

CSV文件内容

设为jackson-core包含以下数据的CSV文件:

data.csv

缺少属性的Java类数据

a;b;c 1;2;0.5 3;4; 代表具有以下属性的数据类:

MyModel

请注意,缺少属性private Long a; private Integer b; ,因此解析器将不得不忽略它。

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

因此c可以与Jackson对象映射器结合使用,以方便的方法将记录从CSV文件中的记录读取到对象列表,

CsvMapper

最后,让我们调用此方法:

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

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

反序列化功能

documentation中,类List<MyModel> result = mapRecordsToObjects(fileInputStream, MyModel.class); 具有以下描述:

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

在此枚举类中,有许多功能具有默认状态(有时每个默认状态都启用,有时被禁用)。如示例所示,可以默认启用DeserializationFeature功能{em> disable 。在其描述中,可以阅读:

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

答案 2 :(得分:0)

这对我有用:

csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);