java - 使用FlatFileItemReader读取csv文件,遇到空列时抛出异常

标签 java spring-boot csv spring-batch

使用FlatFileItemReader读取csv文件时,有一列映射类型为Int,但该列在csv文件中为空(如:6321517,Jack, 1,, 。最后两个列为空)。 解析文件时抛出异常(java.lang.NumberFormatException: Unparseable number)

csv

CUSTR_NBR,SUR_NAME,CHECK_FLAG,RESN_CODE
6321517,Jack,1,,

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

csvItemReader

    @Bean
    @StepScope
    public FlatFileItemReader<InfoDTO> csvItemReader() {
        FlatFileItemReader<InfoDTO> csvItemReader = new FlatFileItemReader<>();
        csvItemReader.setResource(new ClassPathResource("data/charge-off.csv"));
        csvItemReader.setLinesToSkip(1);

        DelimitedLineTokenizer tokenizer=new DelimitedLineTokenizer();
        String[] tokens = new String[]{"CUSTR_NBR","SUR_NAME","CHECK_FLAG","RESN_CODE","EMPNO"};
        tokenizer.setNames(tokens);
        DefaultLineMapper<InfoDTO> lineMapper=new DefaultLineMapper<InfoDTO>();
        lineMapper.setLineTokenizer(tokenizer);
        lineMapper.setFieldSetMapper(new InfoFileMapper());
        lineMapper.afterPropertiesSet();
        csvItemReader.setLineMapper(lineMapper);

        return 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")
            );
        }
    }

我需要将空列映射为0值,如何配置?

最佳答案

我没有使用过 Spring Batch,但查看了 FieldSet Interface specification ,似乎有一些替代方法可以实现您想要的目标。

Spring Batch reference然而,确实提到了一些容错能力,特别是当值不存在时抛出异常。为了禁用此功能,您需要将 strict 设置为 false

tokenizer.setStrict(false);

否则,您可以简单地尝试一些旧的时尚替代方案,例如不要尝试将值直接读取到 int 中,只需将其读入 String 中,然后在将其转换为 String 之前验证该 String 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;
}

这也许不是那么 Eloquent ,但它会起作用并达到目的。

关于java - 使用FlatFileItemReader读取csv文件,遇到空列时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58153998/

相关文章:

java - 在 netbeans 中运行时,tomcat 8.0 出现错误

用于查询 AD 并报告是否在 CSV 文件中找到 UPN 的 PowerShell 脚本

java - 是否可以将普通的java项目转换为springboot项目?

java - 在java中读取csv文件(其中包含字符,整数和特殊符号)并从中提取整数

ios - 如何本地化数据源路径?

java - Java 自动下载计时器

java - httpclient放置问题

java - 如何最小化UDP丢包

java - 为什么camel context无法解析Spring boot fat jar内的路由?

java - 使用 Netflix Eureka 的 JSONException