Spring批量:将读入的文件名传给下一步
Spring Batch: Pass over names of read-in files to the next step
我是 Spring Batch 的新手,我开始使用 Spring Boot & Spring Batch official tutorial.
我遇到的问题是,在使用 spring 批处理读取某些文件后,我想存储这些文件的名称并在下一步中删除它们。
我首先尝试了 StepExecutionContext 来传递数据,但显然我希望传递的数据太大了。因此,我尝试保存初始化 Reader 并在下一步中读取该文件时读取的文件的名称。
@Bean
public MultiResourceItemReader<Widget> widgetMultiReader() {
MultiResourceItemReader<Widget> reader = new MultiResourceItemReader<Widget>();
ClassLoader cl = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
try {
System.out.println("file:" + dataFileLocation + "Widget*.dat");
Resource[] resources = resolver.getResources("file:" + dataFileLocation + "Widget*.dat");
System.out.println("FOUND " + resources.length + " Widget.dat files");
StringBuilder sb = new StringBuilder();
for (int i=0; i<resources.length; i++) {
System.out.println(resources[i].getFilename());
sb.append(resources[i].getFilename());
if(i < resources.length-1){
sb.append("\n");
}
}
reader.setResources(resources);
reader.setDelegate(widgetReader());
File tempFolder = new File(dataFileLocation + Constants.TEMP_FOLDER_NAME);
tempFolder.mkdir();
File tempFile = new File(tempFolder.getAbsolutePath(), "read_in_files.tmp");
tempFile.createNewFile();
FileWriter fileWriter = new FileWriter(tempFile, false);
fileWriter.write(sb.toString());
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
return reader;
}
这一切工作得非常好,但事实证明,如果我这样做,bean 中的代码将自动执行,即使它没有在作业步骤中定义。这显然是因为依赖注入 (Spring boot spring.batch.job.enabled=false not able to recognize)
所以我必须再次改变我的方法,你们能帮帮我吗?
我想做的就是读入一组文本文件,读入里面的数据,存入数据库(这已经做好了)THEN,remove/archive/move那些文件在下一个步骤所以如果有类似 FlatFileParseException 的东西,整个作业将停止并且不会删除文件。
创建可用于在步骤之间传递数据的服务
通过使用 @JobScope
或 @StepScope
注释服务,它将仅在该步骤或作业期间存在。
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List;
@Service
@JobScope
public class FilesService {
private List<File> files;
public List<File> getFiles() {
return files;
}
public void setFiles(List<File> files) {
this.files = files;
}
}
我是 Spring Batch 的新手,我开始使用 Spring Boot & Spring Batch official tutorial.
我遇到的问题是,在使用 spring 批处理读取某些文件后,我想存储这些文件的名称并在下一步中删除它们。
我首先尝试了 StepExecutionContext 来传递数据,但显然我希望传递的数据太大了。因此,我尝试保存初始化 Reader 并在下一步中读取该文件时读取的文件的名称。
@Bean
public MultiResourceItemReader<Widget> widgetMultiReader() {
MultiResourceItemReader<Widget> reader = new MultiResourceItemReader<Widget>();
ClassLoader cl = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
try {
System.out.println("file:" + dataFileLocation + "Widget*.dat");
Resource[] resources = resolver.getResources("file:" + dataFileLocation + "Widget*.dat");
System.out.println("FOUND " + resources.length + " Widget.dat files");
StringBuilder sb = new StringBuilder();
for (int i=0; i<resources.length; i++) {
System.out.println(resources[i].getFilename());
sb.append(resources[i].getFilename());
if(i < resources.length-1){
sb.append("\n");
}
}
reader.setResources(resources);
reader.setDelegate(widgetReader());
File tempFolder = new File(dataFileLocation + Constants.TEMP_FOLDER_NAME);
tempFolder.mkdir();
File tempFile = new File(tempFolder.getAbsolutePath(), "read_in_files.tmp");
tempFile.createNewFile();
FileWriter fileWriter = new FileWriter(tempFile, false);
fileWriter.write(sb.toString());
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
return reader;
}
这一切工作得非常好,但事实证明,如果我这样做,bean 中的代码将自动执行,即使它没有在作业步骤中定义。这显然是因为依赖注入 (Spring boot spring.batch.job.enabled=false not able to recognize)
所以我必须再次改变我的方法,你们能帮帮我吗?
我想做的就是读入一组文本文件,读入里面的数据,存入数据库(这已经做好了)THEN,remove/archive/move那些文件在下一个步骤所以如果有类似 FlatFileParseException 的东西,整个作业将停止并且不会删除文件。
创建可用于在步骤之间传递数据的服务
通过使用 @JobScope
或 @StepScope
注释服务,它将仅在该步骤或作业期间存在。
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List;
@Service
@JobScope
public class FilesService {
private List<File> files;
public List<File> getFiles() {
return files;
}
public void setFiles(List<File> files) {
this.files = files;
}
}