【问题标题】:OpenCSV - CsvReaderNullFieldIndicator seems to make no differenceOpenCSV - CsvReaderNullFieldIndicator 似乎没有什么区别
【发布时间】:2017-03-17 11:20:38
【问题描述】:

我正在使用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 值传递给 .withFieldAsNull()

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

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

我做错了什么?

【问题讨论】:

    标签: java csv opencsv


    【解决方案1】:

    我正在尝试您的方法,但我的行为相同。由于这个库是开源的,我一直在挖掘它为什么会发生。

    • CsvToBean 类中,您有一个 CSVReader 负责 访问要读取的数据。
    • CSVReader 内部,您有一个 CSVParser,它负责获取单个字符串并根据分隔符、引号和转义字符将其解析为元素。
    • CSVParser 包含 CSVReaderNullFieldIndicator(枚举)的成员,用于告诉 CSVParser 什么是 null。

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

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

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

    结论:无论你传递给withFieldAsNull()什么,因为“”或nullStringUtils.isNotBlank()认为是false,因此该字段将为空。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2012-12-17
        • 2014-12-18
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        相关资源
        最近更新 更多