2

我正在使用 Spring Batch 从 CSV 文件中读取并在屏幕上写入行。我的工作由 3 个部分组成: 第 1 部分:验证 CSV 文件是否存在于我磁盘上的某个 INPUT 目录中,如果返回 TRUE,则该文件将被移动到另一个名为 PROD 的目录中。第 2 部分:使用 FlatFileItemReader 从 CSV 文件中提取数据。第 3 部分:将所有项目写入屏幕。

问题是 FlatFileItemReader 抛出org.springframework.batch.item.ItemStreamException: Failed to initialize the readerjava.lang.IllegalArgumentException: Input resource must be set

这是我的代码:

@Bean
public FlatFileItemReader<UniversInvestissement> reader() {
    FlatFileItemReader<UniversInvestissement> reader = new FlatFileItemReader<>();
    File csvFile = new File("C://INPUT/data.csv");
    Resource resource = resourceLoader.getResource("file:" + csvFile.getAbsolutePath());
    reader.setLinesToSkip(1);
    reader.setResource(resource);
    DefaultLineMapper lineMapper = new DefaultLineMapper();

    DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
    tokenizer.setNames(new String[]{"COL1", "COL2", "COL3", "COL4"});
    tokenizer.setDelimiter(";");

    FieldSetMapper fieldSetMapper = new UniversInvestissementFieldSetMapper();
    lineMapper.setLineTokenizer(tokenizer);
    lineMapper.setFieldSetMapper(fieldSetMapper);

    reader.setLineMapper(lineMapper);

    reader.setEncoding("Cp1252");
    return reader;
}

@Bean
public UniversInvestissementWriter writer() {
    return new UniversInvestissementWriter();
}

@Bean
public UniversInvestissementProcessor processor() {
    return new UniversInvestissementProcessor();
}

@Bean
public Step extractData() {
    return steps.get("extractData")
            .<UniversInvestissement, UniversInvestissementProcessorResult>chunk(1)
            .reader(reader())
            .processor(processor())
            .writer(writer())
            .build();
}

实际上的问题是,当它FlatFileItemReader被初始化时,它找不到 CSV 文件作为资源!有没有办法推迟资源分配并避免这种异常?

4

3 回答 3

0

我认为你的问题resourceLoader,因为资源实例的非空断言引发了这样的异常。所以你resourceLoader返回空值。

尝试使用FileSystemResource并且不使用任何资源加载器。例如:

reader.setResource(new FileSystemResource(csvFile));
于 2017-12-29T13:10:58.410 回答
0

reader.setStrict(false); 如果您将严格模式设置为 false,则可以使用阅读器不会引发异常。您可能不得不使用@StepScope使读者变得懒惰。我正在使用相同的设置,它对我来说工作正常,希望这对你有帮助

于 2017-12-27T12:51:22.410 回答
0

验证 CSV 文件是否存在于我磁盘上的某个 INPUT 目录中,如果返回 TRUE,则该文件将移动到另一个名为 PROD 的目录

这个问题可以很容易地使用JobExecutionDecider

class Checker implements JobExecutionDecider {
  FlowExecutionStatus decide(...) {
    if(<file not found in INPUT/ dir>) {
      return FlowExecutionStatus.STOPPED;
    }
    if(!<copy file from INPUT/ to PROD/ works>) {
      return FlowExecutionStatus.FAILED;
    }
    return FlowExecutionStatus.COMPLETED;
  }
}

当然,extractData()必须改为插入使用程序化流决策(查看这里的简单示例)

于 2017-12-29T07:47:31.520 回答