假设我使用Open CSV,并具有类似以下内容:
public class MyDto {
@CsvBindByName(column = "AFBP")
String placeholderA;
@CsvBindByNames({
@CsvBindByName(column = "ABCD"),
@CsvBindByName(column = "AFEL")
})
String placeholderB;
@CsvBindByNames({
@CsvBindByName(column = "ABCD"),
@CsvBindByName(column = "ALTM")
})
String placeholderC;
@Override
public String toString() {
return "placeholder A = " + placeholderA + ", placeholderB = " + placeholderB + ", placeholderC = " + placeholderC;
}
}
反序列化之后
var csv = "AFBP,ABCD\nthis is A,this is B and C";
我得到了
placeholder A = this is A, placeholderB = null, placeholderC = this is B and C
而不是我所需要的
placeholder A = this is A, placeholderB = this is B and C, placeholderC = this is B and C
问题
有没有一种方法,使用这个库或类似的库(提供对注解的支持),来反序列化CSV,使一列到多个字段的Map成为可能?
1条答案
按热度按时间xdnvmnnf1#
不,这是 * 不 * 可能的,至少在OpenCSV版本5.7.1中是这样。* 但是,这可能会在未来的发行版中更改。*
原因在于OpenCSV如何通过
HeaderColumnNameMappingStrategy
注册一个Beans/Pojos字段到列的Map。此生成器足够智能,可以根据以下策略猜测Map策略:
1.如果显式设置了Map策略,则始终使用该策略。
1.如果存在CsvBindByPosition或CsvCustomBindByPosition,则会使用数据行位置Map策略。
1.否则,使用
HeaderColumnNameMappingStrategy
。这包括使用CsvBindByName
或CsvCustomBindByName
的情况。注解将被自动识别。在内部,类
HeaderColumnNameMappingStrategy
将调用registerBinding(..)
。MyPojo
)用作fieldMap
中的Map信息的关键字。遗憾的是,在第168行,当前的实现没有检查是否已经存在键的Map(例如,
ABCD
)。因此,它将用placeholderC
的新绑定覆盖第一个绑定字段placeholderB
。结果,解析将只识别它应该将 csv 输入的值Map到字段**placeholderC
**,正如您所观察到的。我脑子里冒出的唯一念头是:
HeaderNameBaseMappingStrategy
开始扩展,这样就可以正确地处理现有的字段到列的Map。CsvToBeanBuilder#withMappingStrategy(..)
方法注册自定义或多字段策略。因此,您可以通过open a change request来支持所需的行为,这样,现有的Map策略就可以得到改进,以科普您在这里提出的问题所带来的需求。
目前,似乎没有其他选择。