spring batch MultiResourceItemWriter : 如何唯一标识每个写入的文件

spring batch MultiResourceItemWriter : How to uniquely identify each of the written files

在一个步骤中使用 MultiResourceItemWriter 写入多个 CSV 文件。在 Step 中编写各种文件后,我希望能够使用 StepExecutionListener 通过电子邮件将这些文件发送到适当的接收者。

但问题是我如何知道应该将哪些文件发送到哪个电子邮件?文件名或后缀(我有一个自定义的 ResourceSuffixCreator,但它只得到一个索引,无法帮助从另一个有用地识别一个文件。)

使用 spring 启动 2.2.7.

感谢您的帮助。

更新 比如说,我在这份工作中有步骤。成功步骤使用 MultiResourceItemWriter 为每个电子邮件目标输出成功相关文件。

    return this.stepBuilderFactory.get("generateSuccessRecords")
            .<SuccessReport, SuccessReport>chunk(1)
            .reader(successReportItemReader(null, null))
            .processor(itemProcessor)
            .writer(successReportItemWriter(null))
            .build();

successReportItemWriter 是一个委托给

的 MultiResourceItemWriter
    return new MultiResourceItemWriterBuilder<SuccessReport>()
            .name("successReportItemWriter")
            .itemCountLimitPerResource(1)
            .delegate(individualSuccessReportItemWriter())
            .resource(new FileSystemResource(jobReportDirectory + "/successReport"))
            .resourceSuffixCreator(suffixCreator)
            .build();

individualSuccessReportItemWriter() 如下

    FlatFileItemWriter<SuccessReport> itemWriter = new FlatFileItemWriter<>();
    itemWriter.setName("individualSuccessReportItemWriter");
    itemWriter.setHeaderCallback(new SuccesssReportHeaderCallback());
    itemWriter.setLineAggregator(new SuccessReportLineAggregator());

在 Success 步骤生成 SuccessReport 之后,Fallout 步骤将从数据库中查询并重复上述操作,再次使用 MultiResourceItemWriter 为每个电子邮件目标创建 FalloutReport .csv 文件。

目标是能够将成功报告和失败报告 .csv 文件作为附件通过电子邮件发送给每封电子邮件。假设,有 25 个电子邮件目标。 运行 2 个步骤(成功和失败)将生成 25 个成功的 .CSV 文件和 25 个失败的 .CSV 文件。每个电子邮件目标将获得 1 个成功和 1 个 fallout .csv 文件作为附件。

class SuccessReport 和 FalloutReport 在生成 .csv 文件时有电子邮件目标 -- 但是无法这样命名文件,因为后缀 Creator 不允许相应地命名它们。

我想出了一个我觉得有点粗糙的 hack,但希望它会有所帮助。从您的示例代码看来,您使用的块大小为 1,每个 List 元素使用单独的输出文件(对应于您对每个报告的一封目标电子邮件的描述)。在那种情况下,以下建议似乎足够安全。

如果您的 ResourceSuffixCreator were also an ItemWriteListener,您可以将目标电子邮件提取到一个字段变量中,您随后可以将其用于后缀生成。如果您对目标电子邮件执行了某种哈希 (MD5),那么您可能会期望发往给定电子邮件目标的每个报告都存在相同的哈希。

例如:

public class SuccessReportSuffixCreator 
    implements ItemWriteListener<SuccessReport>, ResourceSuffixCreator {

    private String emailTarget = "";

    @Override
    public String getSuffix( int i ) {
        return Md5Crypt.md5Crypt( this.emailTarget.getBytes() ) + "." + i + ".csv";
    }

    @Override
    public void beforeWrite( List<? extends SuccessReport> list ) {
        this.emailTarget = list.get( 0 ).getEmailTarget();
    }

    @Override
    public void afterWrite( List<? extends SuccessReport> list ) {
        // clear emailTarget?
    }

    @Override
    public void onWriteError( Exception e, List<? extends SuccessReport> list ) {
        // clear emailTarget?
    }
}

我不知道这两种报告类型的 class 层次结构是什么样的,因此您要么需要两种不同的 class 用于每种报告类型,要么需要一个 class 对于具有电子邮件目标数据的父类型。

您还需要确保并在 Step 上注册此 ItemWriteListener,以便正确调用其事件处理程序。

我希望这对您有用,或者为您提供解决问题的替代思路。