OpenCSV - CsvReaderNullFieldIndicator 似乎没有什么区别

slu*_*rew 3 java csv opencsv

我正在使用opencsv创建CsvToBean这样的:

CsvToBean<AccountBean> csvToBean = new CsvToBeanBuilder<AccountBean>(new InputStreamReader(inputStream))
                .withFieldAsNull(CSVReaderNullFieldIndicator.NEITHER)
                .withType(AccountBean.class)
                .build();
Run Code Online (Sandbox Code Playgroud)

这是我的AccountBean

public class AccountBean extends BeanBase<Account>
{

    @CsvBindByName(column = "Id", required = true)
    public String salesforceId;

    @CsvBindByName(column = "OwnerId", required = true)
    public String ownerId;

    @CsvBindByName(column = "Name", required = true)
    public String name;

    // billing address
    @CsvBindByName(column = "BillingStreet")
    String billingStreet;
    @CsvBindByName(column = "BillingCity")
    String billingCity;
    @CsvBindByName(column = "BillingState")
    String billingState;
    @CsvBindByName(column = "BillingPostalCode")
    String billingPostcode;
    @CsvBindByName(column = "BillingCountry")
    String billingCountry;

}
Run Code Online (Sandbox Code Playgroud)

问题在于地址字段 - 如果有空白字段,它们始终为空,无论CSVReaderNullFieldIndicator我传递给哪个值.withFieldAsNull()

我的 csv 文件有双引号来表示空字段,因此使用 CSVReaderNullFieldIndicator.NEITHER (无论如何都是默认值)应该生成一个空字符串。

这会导致问题,因为我将空值保存到数据存储区,然后又导致 NullPointerExceptions。

我做错了什么吗?

Jos*_*ães 6

我正在尝试你的方法,我也有同样的行为。由于这个库是开源的,我正在挖掘它发生的原因。

  • 在类内部CsvToBean,您有一个CSVReader负责访问要读取的数据的类。
  • 里面CSVReader有一个 CSVParser,它负责获取单个字符串并根据分隔符、引号和转义字符将其解析为其元素。
  • 包含(enum)CSVParser的成员CSVReaderNullFieldIndicator,用于告知CSVParser将哪些内容视为 null。

当您在代码中调用 build() 时CsvToBeanCSVReaderCSVParser根据您传递给CsvToBeanBuilder.

当您调用时,parse() CSVReader将浏览您的 CSV 文件,并针对每一行调用CSVParser. 根据您的分隔符,解析器将返回一个字符串值数组。此时,基于 NullFieldIndicator 的 CSVParser 会考虑将字符串保留为空或将其设置为 null。最后,如果您有 NullFieldIndicator 属性 asNEITHER并且考虑的行是,例如“one”;“”,则解析器返回的字符串数组将为 [one,""] 或 [one, null] 如果CSVReaderNullFieldIndicatorBOTHEMPTY_QUOTES

在此阶段之后,解析的行将被映射到AccountBean字段。要确定字段是否为空,请使用StringUtils.isNotBlank() 。

结论:无论你传递给 withFieldAsNull() 是什么,因为 "" ornull被认为是falseby StringUtils.isNotBlank(),因此该字段将为空。

您可以询问开发人员这种行为是否是预期的行为。也许他有原因,或者只是一个错误。