我的ItemWriter没有写入任何文件。调试后,它将在ItemProcessor处停止。我的项目应该从Mongo数据库接收信息,然后读取它,对其进行处理,然后创建.txt文件并将信息存储在所述文件中。我在做错什么或我想念什么?
BatchConfig:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
private static final Logger LOG =LoggerFactory.getLogger(BatchConfig.class);
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private PaymentPortalJobListener listener;
@Autowired
private MongoTemplate mongoTemplate;
@Bean
public MongoItemReader<PaymentAudit> mongoReader() throws
UnexpectedInputException, ParseException {
LOG.info("Inside Mongo Item Reader Method");
MongoItemReader<PaymentAudit> reader = new MongoItemReader<PaymentAudit>
();
reader.setTemplate(mongoTemplate);
reader.setCollection("paymentAudit");
reader.setTargetType((Class<? extends PaymentAudit>)
PaymentAudit.class);
reader.setFields("{rxFname, rxLname}");
reader.setQuery("{rxFname, rxLname}");
Map<String, Sort.Direction> sorts = new HashMap<String, Sort.Direction>
(1);
sorts.put("rxFName", Sort.Direction.ASC);
reader.setSort(sorts);
return reader;
}
@Bean
public ItemProcessor<PaymentAudit, PaymentAudit> processor() {
LOG.info("Inside Processor Method");
return new PaymentPortalNOSQLProcessor();
}
@Bean
public ItemWriter<PaymentAudit> writer() {
LOG.info("Inside Writer Method");
return new PaymentPortalNOSQLWriter();
}
@Bean
Job job(JobBuilderFactory jbf, StepBuilderFactory sbf,
PaymentPortalNOSQLProcessor processor,
ItemWriter<? super PaymentAudit> writer) {
Step s1 = sbf.get("local").<PaymentAudit,
PaymentAudit>chunk(100).reader(mongoReader()).processor(processor)
.writer(writer).listener(listener).build();
return jbf.get("etl").incrementer(new
RunIdIncrementer()).start(s1).build();
}
}
PaymentPortalNOSQLWriter:
@Bean
public FileWriter Mongowriter(){
FileWriter writer = null;
try {
String fullPath =OUTPUT_FILENAME + FILENAME_EXTN;
writer = new FileWriter(fullPath);
writer.write("[");
} catch (IOException e) {
LOG.error("Exception occured in MongoWriter() ::
ApplicationConfiguration", e);
}
return writer;
}
@Override
public void write(List items) throws Exception {
}
}
PaymentPortalJobListener
@Autowired
private ApplicationContext appContext;
@Override
public void beforeStep(StepExecution stepExecution) {
long checkpoint = System.currentTimeMillis();
LOG.info("ExamResult Job starts at : {} " , checkpoint / (1_000 * 1.0));
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
if(stepExecution.getStatus() == BatchStatus.COMPLETED){
LOG.info("ExamResult job completed successfully");
try {
FileWriter saveWriter =
(FileWriter)appContext.getBean("paymentPortalWriter");
saveWriter.write("{}");
saveWriter.flush();
saveWriter.close();
} catch (BeansException | IOException e) {
LOG.error("Exception occured in afterStep() :: PaymentPortal",
e);
}
}
return stepExecution.getExitStatus();
}
}
PaymentPortalNOSQLProcessor:
public class PaymentPortalNOSQLProcessor implements
ItemProcessor<PaymentAudit, PaymentAudit> {
private static final Logger LOG =
LoggerFactory.getLogger(PaymentPortalNOSQLProcessor.class);
@Override
public PaymentAudit process(PaymentAudit bean) throws Exception {
LOG.debug("Processor method");
return bean;
}
}
Gradle Build:
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-
plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-batch')
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
//compile("org.hsqldb:hsqldb")
compile('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok')
compile group:'org.springframework.boot', name:'spring-boot-configuration-
processor'
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.batch:spring-batch-test')
// https://mvnrepository.com/artifact/com.h2database/h2
//testCompile group: 'com.h2database', name: 'h2', version: '1.4.197'
}
答案 0 :(得分:0)
在这里,我对I / O有点困惑,所以我会尽力弄清楚。
Spring Batch的主要功能之一是声明性I / O。这意味着您不需要编写代码来处理I / O,而是您声明要执行的操作,Spring Batch将为您执行I / O。您的Mongowriter
bean包含实际写入数据的代码,但实际上不应该。由于您需要写入平面文件,因此可以使用FlatFileItemWriter
,例如:
@Bean
public FlatFileItemWriter<String> flatFileItemWriter() {
return new FlatFileItemWriterBuilder<String>()
.name("flatFileItemWriter")
.resource(new FileSystemResource("data.txt"))
.lineAggregator(new PassThroughLineAggregator<>())
.build();
}
此配置代码声明了我们需要写什么内容以及在哪里写的意图,而不是实际的写操作(打开/关闭文件,调用编写器等),该操作由春季批。顺便说一句,未创建文件的问题是由于未通过代码示例在编写器上调用open
方法。如果您的编写器如上所示正确配置,此问题应该得到解决。
第二点是您之所以这样做,是因为您想在所写的项目周围添加[
和]
(从在代码中看到writer.write("[");
)。还有一次,有一种方法可以通过使用FlatFileHeaderCallback
和FlatFileFooterCallback
API来声明性地执行此操作。例如:
@Bean
public FlatFileItemWriter<String> flatFileItemWriter() {
return new FlatFileItemWriterBuilder<String>()
.name("flatFileItemWriter")
.resource(new FileSystemResource("data.txt"))
.lineAggregator(new PassThroughLineAggregator<>())
.headerCallback(writer -> writer.write('['))
.footerCallback(writer -> writer.write(']'))
.build();
}
希望这会有所帮助。