我目前正在使用Spring批处理来读取文件。我的文件中的某些列可能具有空值。例如,我的文件中的行可能如下所示:
110045,,,50000
此处,第2列和第3列具有空值。第2列将映射到double,第3列将映射到我的域对象中的char。 FieldSetMapper
将按如下方式实施:
public class MyFieldSetMapper implements FieldSetMapper<SomeDomain> {
public SomeDomain mapFieldSet(FieldSet fs) {
final SomeDomain someDomain = new SomeDomain();
someDomain.setAmount(fs.readDouble(1));
someDomain.setIndividualFlag(fs.readChar(2));
someDomain.setBalance(fs.readInt(3,0));
return someDomain;
}
}
上面的FieldSetMapper
实现将在运行时导致异常,因为空String
不能被赋予双精度或字符。
虽然FieldSet
包含readBigDecimal(int,BigDecimal)
或readInt(int,int)
等方法,但如果字符串无法解析为特定类型,则可以指定默认值不为char
或double
提供类似的方法。我不确定将char
和double
类型的默认选项退出后的动机是什么。
我需要的是一种在每个char
字段中为double
和FieldSetMapper
数据类型提供默认值的方法。也就是说,我不想为默认的char
和double
数据类型定义全局策略,但我希望能够像我一样默认这些类型默认为int
或BigDecimal
。
我想过使用FieldSetFactory
来插入扩展FieldSet
的自定义DefaultFieldSet
实现,并提供另外两种方法,即readDouble(int,double)
和readChar(int,char)
public class CustomFieldSet extends DefaultFieldSet {
public CustomFieldSet(String[] tokens, String[] names) {
super(tokens, names);
}
public CustomFieldSet(String[] tokens) {
super(tokens);
}
public char readChar(int index, char defaultValue) {
String value = readAndTrim(index);
return StringUtils.hasLength(value) ? value.charAt(0) : defaultValue;
}
public int readChar(String name, char defaultValue) {
return readChar(indexOf(name), defaultValue);
}
}
然后,我可以将FieldSet
方法的mapFieldSet
参数转换为CustomFieldSet
实现
public class MyFieldSetMapper implements FieldSetMapper<SomeDomain> {
public SomeDomain mapFieldSet(FieldSet fs) {
CustomFieldSet cs = (CustomFieldSet)fs;
final SomeDomain someDomain = new SomeDomain();
someDomain.setAmount(cs.readDouble(1));
someDomain.setIndividualFlag(cs.readChar(2,'\0'));
someDomain.setBalance(cs.readInt(3,0));
return someDomain;
}
}
即使它与弹簧批FieldSet
API无缝集成,这在某种程度上也不是正确的做法。
如果我想以优雅的方式默认char
和double
类型而不是将它们作为String
读取,检查它们是否为空并将它们转换为手动特定类型。