自定义ItemWriter使其像CompositeWriter一样工作以将db和xml写入

时间:2019-01-26 18:28:02

标签: spring-batch

设计批处理以处理xml文件。 将使用StaxEvenItemReader读取XML,并将在处理器中验证输入数据。处理器将返回新的 没有任何验证错误的数据将被持久保存到数据库中,而具有验证错误的数据将被写入不同的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
    }
    }

1 个答案:

答案 0 :(得分:1)

  

没有任何验证错误的数据将被持久保存到数据库中,而具有验证错误的数据将被写入不同的xml结构数据库中。

     

我想知道这是否是一种好习惯

在这种情况下,我不会使用复合ItemWriter。可以跳过“不良数据”,而SkipListener会将其写入其他位置。

  

并且会遇到任何技术挑战。

没有技术挑战,但是存在功能“错误信息”:使用复合ItemWriter,不良数据将被包括在总项目数中,这会产生误导。但是,使用SkipListener,您将拥有一个单独的计数器(writeSkipCount),并且可以区分出良好的数据计数和不良的数据计数。