我正在使用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()
,它们始终为null。我的csv文件用双引号引起来表示一个空字段,因此使用CSVReaderNullFieldIndicator.NEITHER(始终为默认值)应产生一个空字符串。
这会导致问题,因为我将null保存到数据存储中,然后在以后导致NullPointerExceptions。
我做错了什么?
最佳答案
我正在尝试使用您的方法,但行为却相同。由于该库是开源的,因此我一直在寻找原因。
CsvToBean
类中,您具有负责的CSVReader
访问要读取的数据。 CSVReader
内,您有一个CSVParser,它负责将一个字符串作为一个字符串,并根据定界符,引号和转义字符将其解析为其元素。 CSVParser
包含CSVReaderNullFieldIndicator
(枚举)的成员,该成员用于告诉CSVParser
考虑什么为空。 当您在代码
CsvToBean
中调用build()时,将根据传递给CSVReader
的信息实例化CSVParser
和CsvToBeanBuilder
。当您调用
parse()
时,CSVReader
将遍历您的CSV文件,每行将调用CSVParser
。根据您的分隔符,解析器将返回一个String值数组。此时,基于NullFieldIndicator的CSVParser将考虑将字符串保留为空或将其保留为null。最后,如果您具有NullFieldIndicator属性作为NEITHER
,并且考虑的行是例如“one”;“”,则解析器返回的字符串数组将为[one,“”]或如果为CSVReaderNullFieldIndicator
,则为[one,null]是BOTH
或EMPTY_QUOTES
。在此阶段之后,已解析的行将映射到
AccountBean
字段。为了确定该字段为空,使用StringUtils.isNotBlank()。结论:不管您通过FieldAsNull()传递给什么,因为
null
将“”或false
视为StringUtils.isNotBlank()
,因此该字段将为null。您可以询问开发人员此行为是否符合预期。也许他有原因,或者只是一个错误。