在 Spring 批处理中使用 StepScope 注释时出现 WriterNotOpenException
WriterNotOpenException when using StepScope annotation in Spring Batch
我有一个很好用的自定义编写器;但是,我想通过 JobParameters 设置我的输出文件的名称,而不是在我的配置中使用固定的字符串。
为此,我添加了 @StepScope 注释和参数,就像我对 ItemReader 所做的那样。
ItemWriter 声明
@Bean
@StepScope
public ItemWriter<CityProcessed> writer(@Value("#{jobParameters[inputFile]}") String inputFile, @Value("#{jobParameters[outputFile]}") String outputFile) {
// String inputFile = "D:/cities.csv";
// String outputFile = "D:/compterendu.csv";
FlatFileItemWriter<CityCRE> writer = new FlatFileItemWriter<CityCRE>();
FileSystemResource isr;
isr = new FileSystemResource(new File(outputFile));
writer.setResource(isr);
DelimitedLineAggregator<CityCRE> aggregator = new DelimitedLineAggregator<CityCRE>();
aggregator.setDelimiter(";");
BeanWrapperFieldExtractor<CityCRE> beanWrapper = new BeanWrapperFieldExtractor<CityCRE>();
beanWrapper.setNames(new String[]{
"nom", "pays", "identifiantBase", "c/m"
});
aggregator.setFieldExtractor(beanWrapper);
writer.setLineAggregator(aggregator);
CityItemWriter itemWriter = new CityItemWriter();
writer.setFooterCallback(itemWriter);
writer.setHeaderCallback(itemWriter);
itemWriter.setDelegate(writer);
itemWriter.setInputFileName(inputFile);
return itemWriter;
}
步骤声明
@Bean
public Step stepImport(StepBuilderFactory stepBuilderFactory, ItemReader<CityFile> reader, ItemWriter<CityProcessed> writer, ItemProcessor<CityFile, CityProcessed> processor) {
return stepBuilderFactory
.get("step1")
.<CityFile, CityProcessed> chunk(10)
.reader(reader(null))
.processor(processor)
.writer(writer(null, null))
.build();
}
此代码不起作用,由于我将 FlatFileItemWriter 用作委托,我收到 WriterNotOpenException。
当我尝试将 JobParameters 用于我的 ItemReader 时,我遇到了同样的错误,我不得不将 return 类型更改为 "FlatFileItemReader"(而不是 ItemReader)。我不能在这里做同样的事情,因为我需要我的自定义 ItemWriter 而不是简单的 FlatFileItemWriter。
我不明白为什么我在添加 @StepScope 时会出现此错误,而我的 reader 没有它就没有问题。我做错了什么?
附加信息:
- 当我使用 inputFile 和 outputFile 字符串时,我的配置有效。
- 看起来我在添加 @StepScope 注释时出错(即使没有添加 JobParameters 作为我的编写器参数)。
您必须将委托编写器注册为流;这样 SB 将以正确的方式管理流生命周期。
CityItemWriter 由谁实施?
尝试 - 将 public ItemWriter 更改为 FlatFileItemWriter
错误
public ItemWriter
leituraArquivoDelimitadoWriter(@Value("#{jobParameters[[=46=]]}") 资源 arquivoClienteSaida) {
//return 项 -> items.forEach(System.out::println);
return new **FlatFileItemWriterBuilder**<Cliente>()
.name("leituraArquivoDelimitadoWriter")
.resource(arquivoClienteSaida)
.delimited()
.names(new String [] {"nome", "sobrenome", "idade", "email"})
.build();
}
}
消息错误
org.springframework.batch.item.WriterNotOpenException: Writer 必须先打开才能写入
好的
public FlatFileItemWriter
leituraArquivoDelimitadoWriter(@Value("#{jobParameters[[=46=]]}") 资源 arquivoClienteSaida) {
//return 项 -> items.forEach(System.out::println);
return new **FlatFileItemWriterBuilder**<Cliente>()
.name("leituraArquivoDelimitadoWriter")
.resource(arquivoClienteSaida)
.delimited()
.names(new String [] {"nome", "sobrenome", "idade", "email"})
.build();
}
}
在这种情况下将publicItemWriter更改为FlatFileItemWriter解决问题。
我有一个很好用的自定义编写器;但是,我想通过 JobParameters 设置我的输出文件的名称,而不是在我的配置中使用固定的字符串。 为此,我添加了 @StepScope 注释和参数,就像我对 ItemReader 所做的那样。
ItemWriter 声明
@Bean
@StepScope
public ItemWriter<CityProcessed> writer(@Value("#{jobParameters[inputFile]}") String inputFile, @Value("#{jobParameters[outputFile]}") String outputFile) {
// String inputFile = "D:/cities.csv";
// String outputFile = "D:/compterendu.csv";
FlatFileItemWriter<CityCRE> writer = new FlatFileItemWriter<CityCRE>();
FileSystemResource isr;
isr = new FileSystemResource(new File(outputFile));
writer.setResource(isr);
DelimitedLineAggregator<CityCRE> aggregator = new DelimitedLineAggregator<CityCRE>();
aggregator.setDelimiter(";");
BeanWrapperFieldExtractor<CityCRE> beanWrapper = new BeanWrapperFieldExtractor<CityCRE>();
beanWrapper.setNames(new String[]{
"nom", "pays", "identifiantBase", "c/m"
});
aggregator.setFieldExtractor(beanWrapper);
writer.setLineAggregator(aggregator);
CityItemWriter itemWriter = new CityItemWriter();
writer.setFooterCallback(itemWriter);
writer.setHeaderCallback(itemWriter);
itemWriter.setDelegate(writer);
itemWriter.setInputFileName(inputFile);
return itemWriter;
}
步骤声明
@Bean
public Step stepImport(StepBuilderFactory stepBuilderFactory, ItemReader<CityFile> reader, ItemWriter<CityProcessed> writer, ItemProcessor<CityFile, CityProcessed> processor) {
return stepBuilderFactory
.get("step1")
.<CityFile, CityProcessed> chunk(10)
.reader(reader(null))
.processor(processor)
.writer(writer(null, null))
.build();
}
此代码不起作用,由于我将 FlatFileItemWriter 用作委托,我收到 WriterNotOpenException。
当我尝试将 JobParameters 用于我的 ItemReader 时,我遇到了同样的错误,我不得不将 return 类型更改为 "FlatFileItemReader"(而不是 ItemReader)。我不能在这里做同样的事情,因为我需要我的自定义 ItemWriter 而不是简单的 FlatFileItemWriter。
我不明白为什么我在添加 @StepScope 时会出现此错误,而我的 reader 没有它就没有问题。我做错了什么?
附加信息:
- 当我使用 inputFile 和 outputFile 字符串时,我的配置有效。
- 看起来我在添加 @StepScope 注释时出错(即使没有添加 JobParameters 作为我的编写器参数)。
您必须将委托编写器注册为流;这样 SB 将以正确的方式管理流生命周期。
CityItemWriter 由谁实施?
尝试 - 将 public ItemWriter 更改为 FlatFileItemWriter
错误
public ItemWriter leituraArquivoDelimitadoWriter(@Value("#{jobParameters[[=46=]]}") 资源 arquivoClienteSaida) { //return 项 -> items.forEach(System.out::println);
return new **FlatFileItemWriterBuilder**<Cliente>()
.name("leituraArquivoDelimitadoWriter")
.resource(arquivoClienteSaida)
.delimited()
.names(new String [] {"nome", "sobrenome", "idade", "email"})
.build();
}
}
消息错误
org.springframework.batch.item.WriterNotOpenException: Writer 必须先打开才能写入
好的
public FlatFileItemWriter leituraArquivoDelimitadoWriter(@Value("#{jobParameters[[=46=]]}") 资源 arquivoClienteSaida) { //return 项 -> items.forEach(System.out::println);
return new **FlatFileItemWriterBuilder**<Cliente>()
.name("leituraArquivoDelimitadoWriter")
.resource(arquivoClienteSaida)
.delimited()
.names(new String [] {"nome", "sobrenome", "idade", "email"})
.build();
}
}
在这种情况下将publicItemWriter更改为FlatFileItemWriter解决问题。