我可以在 @Value 注释资源中使用占位符吗?

Can I use placeholders in an @Value annotated Resource?

我正在尝试构建一个 Spring 批处理作业,其中用户将目录路径作为输入。此目录中有一个 csv 文件,此文件的名称始终不同。我正在用这个 Java 配置定义我的 ItemReader

@Bean
@StepScope
public FlatFileItemReader<MyObject> itemReader(
        @Value("file:#{jobParameters['directory']}/*.csv") final Resource resource,
        final DefaultLineMapper<MyObject> lineMapper) {
    final FlatFileItemReader<MyObject> reader = new FlatFileItemReader<>();

    reader.setResource(resource);
    reader.setLinesToSkip(1);
    reader.setLineMapper(lineMapper);

    return reader;
}

当我 运行 作业时,出现以下错误:

Caused by: java.lang.IllegalStateException: Input resource must exist (reader is in 'strict' mode): URL [file:C:/path/to/directory/*.csv]
    at org.springframework.batch.item.file.FlatFileItemReader.doOpen(FlatFileItemReader.java:251)
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:144)
    ... 26 more

显然不能在这个地方使用星号作为占位符。还有其他方法可以动态获取csv文件的路径吗?

如果您确定该目录并且总是只有一个 CSV 文件,那么您可以为该目录创建 File 对象并从 listFiles() 中获取第一项,然后创建Resource对象,如下图:

public FlatFileItemReader<MyObject> itemReader(
        @Value("file:#{jobParameters['directory']}") final String resourceDir,
        final DefaultLineMapper<MyObject> lineMapper) {

        File[] files=new File(resourceDir).listFiles(); // you can try giving FileNameFilter for .csv
        File csvFile=files[0]; // do null check and isempty
        // create Resource
        Resource resource = new FileSystemResource(csvFile);
    final FlatFileItemReader<MyObject> reader = new FlatFileItemReader<>();

    reader.setResource(resource);
    reader.setLinesToSkip(1);
    reader.setLineMapper(lineMapper);

    return reader;
}

或者,如果 .csv 文件名有任何静态前缀或后缀,您可以尝试使用现有代码本身。请查看 6.7.2 应用程序上下文构造函数资源路径中的通配符部分 here。例如,假设在您的情况下 .csv 文件具有模式 abc*.csv:

 @Value("file:#{jobParameters['directory']}/abc*.csv")