OpenCSV - CsvReaderNullFieldIndicator似乎没什么区别

时间:2017-03-17 11:20:39

标签: java csv opencsv

我正在使用opencsv创建CsvToBean,如下所示:

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

这是我的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;

}

问题在于地址字段 - 如果有空白字段,则无论我传递给CSVReaderNullFieldIndicator的{​​{1}}值是什么,它们始终为空。

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

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

我做错了什么?

2 个答案:

答案 0 :(得分:2)

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

  • CsvToBean课程内,你有CSVReader负责 访问要读取的数据。
  • CSVReader内你有一个CSVParser,它负责获取一个字符串并根据分隔符,引号和转义字符将其解析为其元素。
  • CSVParser包含CSVReaderNullFieldIndicator(枚举)成员,用于告知CSVParser考虑空的内容。

当您在代码CsvToBean中调用build()时,CSVReaderCSVParser会根据您传递给CsvToBeanBuilder的信息进行实例化。

当您致电parse() CSVReader时,系统会检查您的CSV文件,并且每行都会调用CSVParser。根据您的分隔符,解析器将返回一个String数组值。此时,基于NullFieldIndicator的CSVParser将考虑将字符串保留为空或将其设置为空。最后,如果您将NullFieldIndicator属性设置为NEITHER并且所考虑的行是,例如&#34; one&#34 ;;&#34;&#34;,解析器返回的字符串数组将如果CSVReaderNullFieldIndicatorBOTHEMPTY_QUOTES,则为[one,&#34;&#34;]或[one,null]。

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

结论:无论你传递给withFieldAsNull(),因为&#34;&#34;或nullfalse视为StringUtils.isNotBlank(),因此该字段将为空。

您可以询问开发人员此行为是否是预期的行为。也许他有理由,或者它只是一个错误。

答案 1 :(得分:1)

这需要一些思考,因为问题出现在BeanFieldPrimitiveTypes类中,如果存在值,则只会设置一个值(因此空字段将导致null)。这是因为这是转换为所有类型,大多数不处理空字符串(整数)。因此,需要修改此类以检查字段的类型,以及它是否是特定的一组类型(现在为String),然后允许转换空值。

我在sourceforge中打开的bug中发布了上述内容,我们将尝试在openCSV的4.1或4.2中修复。