我收到一个 csv 文件作为需要加载的 Web 服务调用。现在我将其保存在临时目录中,以将其作为 setResource 提供给 Reader。
有没有办法按原样提供流(byte[])而不是先保存文件?
setResource
的方法ItemReader
将org.springframework.core.io.Resource
作为参数。这个类有一些开箱即用的实现,您可以在其中找到 org.springframework.core.io.InputStreamResource
。该类的构造函数采用 java.io.InputStream
,可以通过 java.io.ByteArrayInputStream
实现。
所以从技术上讲,是的,您可以在
byte[]
中使用 ItemReader
参数。
现在,对于如何实际做到这一点,这里有一些想法:
创建您自己的
FlatFileItemReader
(因为 CSV 是平面文件)并使其实现 StepExecutionListener
公共类 CustomFlatFileItemReader 扩展 FlatFileItemReader 实现 StepExecutionListener { }
重写
beforeStep
方法,在其中进行 Web 服务调用并将结果保存在变量中
私有字节[]流;
@覆盖 公共无效beforeStep(StepExecution stepExecution){
// your webservice logic
stream = yourWebservice.results();
}
重写
setResource
方法以将此 stream
作为实际资源传递。
@覆盖 公共无效setResource(资源资源){
// Convert byte array to input stream
InputStream is = new ByteArrayInputStream(stream);
// Create springbatch input stream resource
InputStreamResource res = new InputStreamResource(is);
// Set resource
super.setResource(res);
}
此外,如果您不想在 ItemReader 中调用 Web 服务,您可以简单地将字节数组存储在
JobExecutionContext
中,并使用 beforeStep
在
stepExecution.getJobExecution().getExecutionContext().get("key");
方法中获取它
我现在正在使用 FlaFileItemReader,从 Google Storage 读取文件。无需扩展:
@Bean
@StepScope
public FlatFileItemReader<MyDTO> itemReader(@Value("#{jobParameters['filename']}") String filename) {
InputStream stream = googleStorageService.getInputStream(GoogleStorage.UPLOADS, filename);
return new FlatFileItemReaderBuilder<MyDTO>()
.name("myItemReader")
.resource(new InputStreamResource(stream)) //InputStream here
.delimited()
.names(FIELDS)
.lineMapper(lineMapper()) // Here is mapped like a normal File
.fieldSetMapper(new BeanWrapperFieldSetMapper<MyDTO>() {{
setTargetType(MyDTO.class);
}})
.build();
}