2017-03-17 244 views
2

我使用opencsv创建CsvToBean这样的:OpenCSV - CsvReaderNullFieldIndicator似乎没有什么区别

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值传递给.withFieldAsNull()

我的csv文件有双引号来表示一个空字段,所以使用CSVReaderNullFieldIndicator.NEITHER(这是默认情况下)应该产生一个空字符串。

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

我做错了什么?

回答

2

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

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

当你在代码中调用生成()CsvToBeanCSVReaderCSVParser是基于你传递给CsvToBeanBuilder的信息实例化。

当您拨打parse()CSVReader将通过您的CSV文件并为每一行将调用CSVParser。基于你的分隔符,解析器将返回一个String数组值。此时,基于NullFieldIndicator的CSVParser将考虑将该字符串保留为空或将其设置为空。最后,如果您有NullFieldIndicator属性为NEITHER,并且所考虑的行是例如“one”;“”,则分析器返回的字符串数组将为[one,“”]或[one,null]如果CSVReaderNullFieldIndicatorBOTHEMPTY_QUOTES

经过这个阶段后,解析的行将被映射到AccountBean字段。要使用该字段为空StringUtils.isNotBlank()

结论:不管你通过什么withFieldAsNull(),因为“”或null被认为是falseStringUtils.isNotBlank(),因此该领域将是无效的。

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

1

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

我贴在上面,你在sourceforge上开辟了错误,我们会尽量在任一4.1或openCSV的4.2得到修复。