Spring batch - java.lang.IllegalStateException:已读取InputStream-不使用InputStreamResource

tp5buhyn  于 2023-06-04  发布在  Java
关注(0)|答案(1)|浏览(246)

我在简单的spring批处理作业中为FlatFileItemReader定义了以下内容:

@Bean
  public FlatFileItemReader<BookingInfo> bookingInfoReader() {
    FlatFileItemReader<BookingInfo> itemReader = new FlatFileItemReader<>();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    BlobClient blobClient =
        blobContainerClient.getBlobClient("path/file.csv");
    blobClient.downloadStream(outputStream);
    final byte[] bytes = outputStream.toByteArray();
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    InputStreamResource resource = new InputStreamResource(inputStream);
    itemReader.setResource(resource);
    itemReader.setName("csvReader");
    itemReader.setLinesToSkip(1);
    itemReader.setLineMapper(lineMapper());
    return itemReader;
  }

但我得到了错误:java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
现在,我将上面的代码改为使用ByteArrayResource,如下所示:

@Bean
  public FlatFileItemReader<BookingInfo> bookingInfoReader {

    FlatFileItemReader<BookingInfo> itemReader = new FlatFileItemReader<>();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    BlobClient blobClient =
        blobContainerClient.getBlobClient("path/file.csv");
    blobClient.downloadStream(outputStream);
    final byte[] bytes = outputStream.toByteArray();
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    
    ByteArrayResource byteArrayResource = new ByteArrayResource(inputStream.readAllBytes());
    itemReader.setResource(byteArrayResource); 

    itemReader.setName("csvReader");
    itemReader.setLinesToSkip(1);
    itemReader.setLineMapper(lineMapper());
    return itemReader;
  }

现在,上述错误消失了。然而,有一个奇怪的问题。即使我更新了文件内容,在触发作业时也不会动态获取。相反,它使用相同的旧内容。仅在pod重新启动后才接受修改后的内容。我相信这是由于reader bean创建一次并每次使用它的事实。
因此,我需要通过修复前面提到的问题回到InputStreamResource实现。这里出了什么问题?

nszi6y05

nszi6y051#

我相信这是由于reader bean创建一次并每次使用它的事实。
是的,您共享的reader bean定义的作用域是单例的。因此,相同的示例将用于整个应用生命周期,并且文件内容将相同。
您应该通过在其bean定义方法上添加@StepScope来使读取器成为step-scoped,以便在每次运行时创建一个新示例。

相关问题