从 spring 批处理 itemReader 中的流而不是文件读取
Reading from streams instead of files in spring batch itemReader
我收到一个 csv 文件作为网络服务调用,需要加载。现在我将它保存在临时目录中以将其作为 setResource 提供给 Reader.
有没有办法按原样提供 stream(byte[]) 而不是先保存文件?
ItemReader
的方法setResource
以org.springframework.core.io.Resource
作为参数。 class 有一些开箱即用的实现,您可以在其中找到 org.springframework.core.io.InputStreamResource
。这个 class' 构造函数采用 java.io.InputStream
可以由 java.io.ByteArrayInputStream
实现。
所以从技术上讲,是的,您可以在 ItemReader
.
中使用 byte[]
参数
现在,关于如何实际做到这一点,这里有一些想法:
1) 创建您自己的 FlatFileItemReader
(因为 CSV 是平面文件)并使其实现 StepExecutionListener
public class CustomFlatFileItemReader<T> extends FlatFileItemReader<T> implements StepExecutionListener {
}
2) 覆盖 beforeStep
方法,在其中执行您的网络服务调用并将结果保存在变量中
private byte[] stream;
@Override
public void beforeStep(StepExecution stepExecution) {
// your webservice logic
stream = yourWebservice.results();
}
3) 覆盖 setResource
方法以将此 stream
作为实际资源传递。
@Override
public void setResource(Resource resource) {
// 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 中调用您的网络服务,您可以简单地将字节数组存储在 JobExecutionContext
中,然后在 beforeStep
方法中使用 stepExecution.getJobExecution().getExecutionContext().get("key");
我现在正在使用 FlatFileItemReader,从 Google 存储中读取文件。无需扩展:
@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();
}
我收到一个 csv 文件作为网络服务调用,需要加载。现在我将它保存在临时目录中以将其作为 setResource 提供给 Reader.
有没有办法按原样提供 stream(byte[]) 而不是先保存文件?
ItemReader
的方法setResource
以org.springframework.core.io.Resource
作为参数。 class 有一些开箱即用的实现,您可以在其中找到 org.springframework.core.io.InputStreamResource
。这个 class' 构造函数采用 java.io.InputStream
可以由 java.io.ByteArrayInputStream
实现。
所以从技术上讲,是的,您可以在 ItemReader
.
byte[]
参数
现在,关于如何实际做到这一点,这里有一些想法:
1) 创建您自己的 FlatFileItemReader
(因为 CSV 是平面文件)并使其实现 StepExecutionListener
public class CustomFlatFileItemReader<T> extends FlatFileItemReader<T> implements StepExecutionListener {
}
2) 覆盖 beforeStep
方法,在其中执行您的网络服务调用并将结果保存在变量中
private byte[] stream;
@Override
public void beforeStep(StepExecution stepExecution) {
// your webservice logic
stream = yourWebservice.results();
}
3) 覆盖 setResource
方法以将此 stream
作为实际资源传递。
@Override
public void setResource(Resource resource) {
// 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 中调用您的网络服务,您可以简单地将字节数组存储在 JobExecutionContext
中,然后在 beforeStep
方法中使用 stepExecution.getJobExecution().getExecutionContext().get("key");
我现在正在使用 FlatFileItemReader,从 Google 存储中读取文件。无需扩展:
@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();
}