Java OpenCSV-CsvReaderNullFieldIndicator似乎没有什么区别

Java OpenCSV-CsvReaderNullFieldIndicator似乎没有什么区别,java,csv,opencsv,Java,Csv,Opencsv,我正在使用创建一个CsvToBean,如下所示: CsvToBean<AccountBean> csvToBean = new CsvToBeanBuilder<AccountBean>(new InputStreamReader(inputStream)) .withFieldAsNull(CSVReaderNullFieldIndicator.NEITHER) .withType(AccountBean.

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

CsvToBean<AccountBean> csvToBean = new CsvToBeanBuilder<AccountBean>(new InputStreamReader(inputStream))
                .withFieldAsNull(CSVReaderNullFieldIndicator.NEITHER)
                .withType(AccountBean.class)
                .build();
问题在于地址字段-如果存在空白字段,则无论我传递给
.withFieldAsNull()
的值是哪个
CSVReaderNullFieldIndicator
值,地址字段始终为空

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

这会导致问题,因为我正在将null保存到我的数据存储中,然后它会在以后导致NullPointerException


我做错了什么吗?

我在尝试你的方法,我也有同样的行为。因为这个库是开源的,所以我一直在挖掘它为什么会发生

  • CsvToBean
    类中,您有一个
    CSVReader
    负责 访问要读取的数据
  • CSVReader
    中,您有一个CSVParser,负责获取单个字符串,并根据分隔符、引号和转义字符将其解析为元素
  • <> LI> <代码> CSVParser <代码>包含一个代码> CsReaveRululnFieldStudio(EnUM)的成员,用于告诉<代码> CSVParser <代码>什么是NULL。
在代码
CsvToBean
中调用build()时,
CSVReader
CSVParser
将根据传递给
CsvToBeanBuilder
的信息进行实例化

当您调用
parse()
CSVReader
时,它将遍历您的CSV文件,并为每一行调用
CSVParser
。根据分隔符,解析器将返回值的字符串数组。此时,基于nulffield指示符的CSVPARSER将考虑将字符串保留为空或将其设为NULL。最后,如果您将NullFieldIndicator属性设置为
,并且所考虑的行是,例如,“一”;如果
CSVReaderNullFieldIndicator
两者都是
空引号,则解析器返回的字符串数组将是[one,”]或[one,null]

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

结论:无论您用字段asnull()传递什么,因为
StringUtils.isNotBlank()
将“”或
null
视为
false
,因此该字段将为null


您可以询问开发人员此行为是否为预期行为。可能他有原因,或者只是一个bug。

这需要一些思考,因为问题在BeanFieldPrimitiveTypes类中,该类仅在有值时设置值(因此空字段将导致null)。这是因为它正在转换为所有类型,并且大多数不处理空字符串(整数)。因此需要修改这个类来检查字段的类型,如果它是一组特定的类型(现在是String),则允许转换空值

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

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;

}