Spring batch 自定义ItemWriter,使其工作方式与CompositeWriter类似,以将数据写入db和xml

Spring batch 自定义ItemWriter,使其工作方式与CompositeWriter类似,以将数据写入db和xml,spring-batch,Spring Batch,设计批处理以处理xml文件。 XML将使用StateVenitemReader读取,输入数据将在处理器中验证。处理器将返回新的 没有任何验证错误的数据将被持久化到数据库中,有验证错误的数据将被写入到不同xml结构的数据库中。 我已经扩展了ItemWriter来定制写作。我想知道这是否是一种良好的做法,是否会受到任何技术挑战的影响 下面是作业配置 @Bean public StaxEventItemReader<CustomerRequest> xmlReader() {

设计批处理以处理xml文件。 XML将使用StateVenitemReader读取,输入数据将在处理器中验证。处理器将返回新的 没有任何验证错误的数据将被持久化到数据库中,有验证错误的数据将被写入到不同xml结构的数据库中。 我已经扩展了ItemWriter来定制写作。我想知道这是否是一种良好的做法,是否会受到任何技术挑战的影响

下面是作业配置

@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实现的实际场景。