Spring batch 自定义ItemWriter,使其工作方式与CompositeWriter类似,以将数据写入db和xml
设计批处理以处理xml文件。 XML将使用StateVenitemReader读取,输入数据将在处理器中验证。处理器将返回新的 没有任何验证错误的数据将被持久化到数据库中,有验证错误的数据将被写入到不同xml结构的数据库中。 我已经扩展了ItemWriter来定制写作。我想知道这是否是一种良好的做法,是否会受到任何技术挑战的影响 下面是作业配置Spring batch 自定义ItemWriter,使其工作方式与CompositeWriter类似,以将数据写入db和xml,spring-batch,Spring Batch,设计批处理以处理xml文件。 XML将使用StateVenitemReader读取,输入数据将在处理器中验证。处理器将返回新的 没有任何验证错误的数据将被持久化到数据库中,有验证错误的数据将被写入到不同xml结构的数据库中。 我已经扩展了ItemWriter来定制写作。我想知道这是否是一种良好的做法,是否会受到任何技术挑战的影响 下面是作业配置 @Bean public StaxEventItemReader<CustomerRequest> xmlReader() {
@Bean
public StaxEventItemReader<CustomerRequest> xmlReader() {
StaxEventItemReader<CustomerRequest> itemReader = new StaxEventItemReader<>();
fileName="customer.xml";
FileSystemResource inputFile = new FileSystemResource(Paths.get(inputDirectory,fileName));
itemReader.setResource(inputFile);
itemReader.setStrict(true);
itemReader.setFragmentRootElementName("customer");
itemReader.setUnmarshaller(xmlReadMarshaller());
return itemReader;
}
public Jaxb2Marshaller xmlReadMarshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller ();
marshaller.setClassesToBeBound(CustomerRequest.class);
return marshaller;
}
public Jaxb2Marshaller xmlWriteMarshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller ();
marshaller.setClassesToBeBound(CustomerResponse.class);
return marshaller;
}
@Bean
public CompositeWriter compositeCustomerWriter(CustomerItemWriter customerItemWriter,StaxEventItemWriter<CustomerResponse> customerStaxEventItemWriter) {
CompositeWriter cw = new CompositeWriter();
cw.setCustomerItemWriter(customerItemWriter);
cw.setCustomerXmlWriter(customerStaxEventItemWriter);
return cw;
}
@Bean
public StaxEventItemWriter<CustomerResponse> customerStaxEventItemWriter() {
StaxEventItemWriterBuilder<CustomerResponse> staxBuilder = new StaxEventItemWriterBuilder<>();
FileSystemResource outputFile = new FileSystemResource(Paths.get(inputDirectory,"output.xml"));
return staxBuilder.name("ResponseFile")
.rootTagName("CustomerResponse")
.marshaller(xmlWriteMarshaller())
.resource(outputFile)
.build();
}
@Bean
public TaskletStep createCustomerStep(CustomerProcessor customerProcessor,CustomerItemWriter customerItemWriter,StaxEventItemWriter<CustomerResponse> customerStaxEventItemWriter) {
CompositeWriter compositeInvoiceWriter = compositeInvoiceWriter(customerItemWriter,customerStaxEventItemWriter);
return stepBuilderFactory.get(CREATE_INVOICE_STEP)
.<CustomerRequest,CustomerData>chunk(100)
.reader(xmlReader())
.processor(customerProcessor)
.writer(compositeCustomerWriter(customerItemWriter,customerStaxEventItemWriter))
.stream(customerStaxEventItemWriter)
.build();
}
public class CompositeWriter implements ItemWriter<CustomerData> {
private ItemWriter<CustomerData> customerItemWriter;
private StaxEventItemWriter<CustomerResponse> customerXmlWriter;
@Override
public void write(List<? extends CustomerData> items) throws Exception {
customerItemWriter.write(items);
customerXmlWriter.write(convertToCustomerResponse(items))); converting to different type and calling write n staxevenitem writer
}
}
@Bean
public statxeventitemreader xmlReader(){
statxeventitemreader itemReader=新的statxeventitemreader();
fileName=“customer.xml”;
FileSystemResource inputFile=新的FileSystemResource(path.get(inputDirectory,fileName));
setResource(inputFile);
itemReader.setStrict(true);
setFragmentRootElementName(“客户”);
setUnmarshaller(xmlReadMarshaller());
返回项目阅读器;
}
公共Jaxb2Marshaller xmlReadMarshaller(){
Jaxb2Marshaller-marshaller=新的Jaxb2Marshaller();
setClassesToBeBound(CustomerRequest.class);
返回编组员;
}
公共Jaxb2Marshaller xmlWriteMarshaller(){
Jaxb2Marshaller-marshaller=新的Jaxb2Marshaller();
setClassesToBeBound(CustomerResponse.class);
返回编组员;
}
@豆子
公共CompositeWriter CompositeCostomerWriter(CustomerItemWriter CustomerItemWriter,StatexEventWriter CustomerTaxeEventItemWriter){
CompositeWriter cw=新的CompositeWriter();
cw.setCustomerItemWriter(customerItemWriter);
cw.setCustomerXmlWriter(CustomerTaxeventionItemWriter);
返回cw;
}
@豆子
公共StateVentitemWriter客户税务VentitemWriter(){
StaxEventItemWriterBuilder staxBuilder=新的StaxEventItemWriterBuilder();
FileSystemResource outputFile=新的FileSystemResource(path.get(inputDirectory,“output.xml”);
返回staxBuilder.name(“ResponseFile”)
.rootTagName(“CustomerResponse”)
.marshaller(xmlWriteMarshaller())
.resource(输出文件)
.build();
}
@豆子
公共TaskletStep createCustomerStep(CustomerProcessor CustomerProcessor、CustomerItemWriter CustomerItemWriter、StateVentitemWriter CustomerTaxeVentitemWriter){
CompositeWriter compositeInvoiceWriter=compositeInvoiceWriter(customerItemWriter、CustomerTaxeVentientItemWriter);
返回stepBuilderFactory.get(创建发票步骤)
.chunk(100)
.reader(xmlReader())
.处理器(customerProcessor)
.writer(CompositeCostomerWriter(customerItemWriter,CustomerTaxeVentientItemWriter))
.stream(customerStaxEventItemWriter)
.build();
}
公共类CompositeWriter实现ItemWriter{
私人项目编写器customerItemWriter;
私人StatxeventitemWriter customerXmlWriter;
@凌驾
公共空白写入(列表)
没有任何验证错误的数据将被持久化到数据库中,有验证错误的数据将被写入到不同xml结构的数据库中
我想知道这是否是一种良好的做法
在这种情况下,我不会使用复合ItemWriter。可以跳过“坏数据”,而SkipListener
会将其写入不同的位置
并将面临任何技术挑战
没有技术上的挑战,但存在功能上的“错误信息”:对于复合ItemWriter,错误数据将包含在项目总数中,这是误导性的。但是,对于SkipListener
,您将有一个单独的计数器(writeSkipCount)您将能够区分好的数据计数和坏的数据计数。感谢您的回复。我想用示例进一步解释我的问题。假设该批处理正在处理50条记录。在50条记录中,有10条记录包含坏数据。在这种情况下,我需要将40条记录写入数据库,并将所有50条记录写入xml文件,作为对fi的响应le提供程序(无论是否处理记录)。这是我试图使用compositeWriter实现的实际场景。