3

我的问题是我需要将具有任意列/顺序的 CSV 文件解析为已知域 POJO(比如 Person)。我可以确定我需要处理哪些列,而忽略其余列。

选项 CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE" 似乎正是我需要的,但我需要处理的列不必在 CSV 文件的开头进行分组,我不能强制用户“重新排序”列他们上传的 CSV 文件。此外,有时我没有得到标题行,但 UI 会强制用户识别列并传递此信息。

例如,我有以下 CSV 文件:

First Name,Last Name,Nickname,DOB,Occupation,Postal Code
Freddy,Benson,Ruprecht,08/14/45,Con Artist,76701
Lawrence,Jamieson,Prince,03/14/33,Con Artist,5201
Janet,Colgate,Jackal,03/13/55,Con Artist,90401

我只需要 6 列中的 4 列(名字、姓氏、出生日期、邮政编码),因为我的 Person POJO 仅包含这些字段:

public class Person {
    private String firstName;
    private String lastName;
    private LocalDate dob;
    private String postalCode;
}

我已经为 Person 定义了一个 CsvSchema,并指定了我感兴趣的列(名字、姓氏、IGNORE、DOB、IGNORE2、邮政编码),因为我想跳过列(昵称、职业)。然而,“IGNORE”列在反序列化器中的映射过程中被忽略,我最终得到“DOB”的“昵称”值,导致 DOB 字段的值无效。

4

3 回答 3

3

我的错误是将模式定义如下,这显然将模式与域 POJO 强耦合:

CsvSchema schema = mapper
    .typedSchemaFor(Person.class)
    .withSkipFirstDataRow(hasHeader)
    .sortedBy(columnOrder.toArray(new String[columnOrder.size()]));

通过如下定义模式/列来解决,这似乎将模式松散地耦合到域 POJO:

CsvSchema schema = CsvSchema.builder()
    .addColumn("firstName")
    .addColumn("lastName")
    .addColumn("ignore1")
    .addColumn("dob")
    .addColumn("ignore2")
    .addColumn("postalCode")
    .build();

    CsvMapper mapper = new CsvMapper();
    MappingIterator<Person> personIter = mapper
            .readerFor(Person.class)
            .with(schema)
            .readValues(csvFile);
于 2019-05-10T14:10:40.057 回答
1

请参阅提供的此链接

你应该能够解决这个https://github.com/FasterXML/jackson-dataformat-csv/issues/82

于 2019-05-09T21:18:21.983 回答
0

忽略未知可以实现如下所示(使用jackson 2.13测试):

  1. 注释 POJO
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDate;

@JsonIgnoreProperties(ignoreUnknown = true) //this is the trick to ignore all undeclared columns
public class Person {
    @JsonProperty("First Name") //declare what's needed
    private String firstName;
    private String lastName;
    private LocalDate dob;
    private String postalCode;
}
  1. 配置 csvSchema
CsvMapper csvMapper = new CsvMapper();
CsvSchema csvSchema = csvMapper
    .schemaFor(Person.class)
    .withHeader()//header defines the order
    .withColumnReordering(true)//this allows columns to be in any order as long as there is a header
    ;
  1. 最后,用它来读取csv文件
csvMapper.readerFor(Person.class).with(csvSchema).readValues(csvFile)
于 2022-02-09T18:11:19.167 回答