Java 使用FlatFileItemReader读取csv文件,遇到空列时引发异常

Java 使用FlatFileItemReader读取csv文件,遇到空列时引发异常,java,spring-boot,csv,spring-batch,Java,Spring Boot,Csv,Spring Batch,使用FlatFileItemReader读取csv文件时,列映射类型为Int,但此列在csv文件中为null(例如:6321517,Jack,1,,。最后两列为空)。 解析文件时引发异常(java.lang.NumberFormatException:不可解析的数字) csv 第一行数据(CUSTR_NBR、SUR_NAME、CHECK_FLAG、RESN_CODE)首先被解析,因此我设置.SetLinesToSkip(1)。但是,如果解析空值,则无法正常执行相应的“CHECK_FLAG”和“R

使用FlatFileItemReader读取csv文件时,列映射类型为Int,但此列在csv文件中为null(例如:
6321517,Jack,1,,
。最后两列为空)。 解析文件时引发异常(
java.lang.NumberFormatException:不可解析的数字

csv

第一行数据(CUSTR_NBR、SUR_NAME、CHECK_FLAG、RESN_CODE)首先被解析,因此我设置.SetLinesToSkip(1)。但是,如果解析空值,则无法正常执行相应的“CHECK_FLAG”和“RESN_CODE”。我相信有一个对应的配置项。我查看了springbatch的文档,没有找到任何相关的配置项

csvItemReader

@Bean
@步进镜
公共FlatFileItemReader csvItemReader(){
FlatFileItemReader csvItemReader=新的FlatFileItemReader();
setResource(新类路径资源(“data/chargeoff.csv”);
csvItemReader.setLinesToSkip(1);
DelimitedLineTokenizer标记器=新DelimitedLineTokenizer();
String[]tokens=新字符串[]{“CUSTR_NBR”、“SUR_NAME”、“CHECK_FLAG”、“RESN_CODE”、“EMPNO”};
tokenizer.setNames(令牌);
DefaultLineMapper lineMapper=新的DefaultLineMapper();
lineMapper.setLineTokenizer(标记器);
setFieldSetMapper(新的InfoFileMapper());
lineMapper.afterPropertieSet();
csvItemReader.setLineMapper(lineMapper);
返回csvItemReader;
}
制图员

    public class InfoFileMapper implements FieldSetMapper<ChargeOffBatchDTO> {
        @Override
        public InfoDTO mapFieldSet(FieldSet fieldSet) throws BindException {

            if(fieldSet == null){
                return null;
            }

            return new InfoDTO(
                fieldSet.readString("CUSTR_NBR"),
                fieldSet.readString("SUR_NAME"),
                fieldSet.readString("CHECK_FLAG"),
                fieldSet.readInt("RESN_CODE"),
                fieldSet.readInt("EMPNO")
            );
        }
    }
公共类InfoFileMapper实现FieldSetMapper{
@凌驾
公共信息到映射字段集(字段集字段集)引发BindException{
如果(字段集==null){
返回null;
}
返回新信息到(
fieldSet.readString(“客户编号”),
fieldSet.readString(“SUR_NAME”),
fieldSet.readString(“检查标志”),
fieldSet.readInt(“RESN_代码”),
fieldSet.readInt(“EMPNO”)
);
}
}

我需要将空列映射到0的值。如何配置?

我没有使用Spring批处理,但是看看,似乎有一些方法可以实现您想要的

但是,在不存在值时,确实提到了一些容错性,特别是在抛出异常方面。要禁用此功能,您需要将strict设置为
false

tokenizer.setStrict(false);
否则,您可以简单地尝试一些旧式的替代方法,例如不尝试将值直接读入
int
,而是将其读入字符串,然后在将其转换为
int
之前验证该字符串

String empNo = fieldSet.readString("EMPNO");
if ((empNo == null) || (empNo.equals(""))) {
  empNo = "0";
}
int i = Integer.valueOf(empNo);
如果字段不是空且不是字符串,您仍然可能会得到
java.lang.NumberFormatException
,因此我个人只需通过处理异常来解决问题:

int myEmp = 0;
try {
  myEmp = fieldSet.readInt("EMPNO");
} catch (NumberFormatException nfe) {
  myEmp = 0;
}

它也许没有那么雄辩,但它会起作用并达到目的

您可以创建自己的行映射器实现,检查子字符串是否为空,并将其替换为零,然后向前传递该行。

可能的重复项
int myEmp = 0;
try {
  myEmp = fieldSet.readInt("EMPNO");
} catch (NumberFormatException nfe) {
  myEmp = 0;
}