jackson-dataformat-csv 不会忽略未知属性
jackson-dataformat-csv does not ignore unknown properties
正在尝试使用 jackson-dataformat-csv 解析 .csv 文件。文件包含许多与我的程序无关的列。
尝试对我的数据 class 使用 @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 中不需要的列?
找到解决方案:
csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)
这对我有用:
csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
简介
为了便于理解,这里有一个简单的 (Java) 示例:
从 InputStream 读取 CSV 文件 (jackson-dataformat-csv
依赖)
将其内容映射到对象列表(jackson-core
依赖项)
CSV 文件内容
设 data.csv
一个包含以下数据的 CSV 文件:
a;b;c
1;2;0.5
3;4;
Java Class 缺少属性的数据
classMyModel
表示一个数据class具有以下属性:
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。
反序列化功能
在documentation中,classDeserializationFeature
有如下描述:
Enumeration that defines simple on/off features that affect the way
Java objects are deserialized from JSON
在此枚举中 class,有许多功能具有默认状态(有时默认启用,有时禁用)。功能 FAIL_ON_UNKOWN_PROPERTIES
默认为 禁用 可以启用,如示例所示。在其描述中,可以看到:
Feature that determines whether encountering of unknown properties
(ones that do not map to a property, and there is no "any setter" or
handler that can handle it) should result in a failure (by throwing a
{@link JsonMappingException}) or not.
正在尝试使用 jackson-dataformat-csv 解析 .csv 文件。文件包含许多与我的程序无关的列。
尝试对我的数据 class 使用 @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 中不需要的列?
找到解决方案:
csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)
这对我有用:
csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
简介
为了便于理解,这里有一个简单的 (Java) 示例:
从 InputStream 读取 CSV 文件 (
jackson-dataformat-csv
依赖)将其内容映射到对象列表(
jackson-core
依赖项)
CSV 文件内容
设 data.csv
一个包含以下数据的 CSV 文件:
a;b;c
1;2;0.5
3;4;
Java Class 缺少属性的数据
classMyModel
表示一个数据class具有以下属性:
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。
反序列化功能
在documentation中,classDeserializationFeature
有如下描述:
Enumeration that defines simple on/off features that affect the way Java objects are deserialized from JSON
在此枚举中 class,有许多功能具有默认状态(有时默认启用,有时禁用)。功能 FAIL_ON_UNKOWN_PROPERTIES
默认为 禁用 可以启用,如示例所示。在其描述中,可以看到:
Feature that determines whether encountering of unknown properties (ones that do not map to a property, and there is no "any setter" or handler that can handle it) should result in a failure (by throwing a {@link JsonMappingException}) or not.