2017-03-01 6 views
1

以下のスプリングバッチを使用して属性値に基づいてXMLを解析するには、参照用のXMLです。上記のXMLのSpringバッチを使用して属性値に基づいてXMLフラグメントを解析します。

<?xml version="1.0" encoding="UTF-8"?> 
<customerInfo> 
<cutommer dept="IT"> 
<param value="Jane" name="first-name"/> 
<param value="Doe" name="last-name"/> 
<param value="17 Streets" name="address"/> 
<param value="1234567" name="phone-number"/> 
</customer> 
<cutommer dept="ES"> 
<param value="Jane" name="first-name"/> 
<param value="Doe" name="last-name"/> 
<param value="17 Streets" name="address"/> 
<param value="1234567" name="phone-number"/> 
</customer> 
</customerInfo> 

ベースはDEPTのatribute値は、 "IT" の.ANYのヘルプがにappriciatedされているのみお客様タグを解析する

アップデート1:

@Configuration 
@EnableBatchProcessing 
public class ControllerInfoParser_Config extends DefaultBatchConfigurer { 

    @Autowired 
    private JobBuilderFactory jobs; 
    @Autowired 
    private StepBuilderFactory steps; 
    @Bean 
    public Job parseComponentInfoXML(Step parseComponentInfo,Step partitionStep, CustomJobExecutionerListener customJobExecutionerListener) 
      throws UnexpectedInputException, ParseException, Exception { 

     return jobs.get("parseComponentInfoXML").listener(customJobExecutionerListener).start(parseComponentInfo) 
       .next(partitionStep).build(); 


    } 
    @Bean 
    public Step parseComponentInfo(ItemReader<Customer> oneDeptITItemReader) throws UnexpectedInputException, ParseException, Exception { 

     return steps.get("parseComponentInfo").<Customer, Customer> chunk(1) 
       .reader(componentInfoReader()).reader(oneDeptITItemReader).processor(componentInfoProcessor()) 
       .writer(componentInfoWriter()).build(); 
    } 

    @Bean 
    public ItemReader<Customer> componentInfoReader() throws UnexpectedInputException, ParseException, Exception { 

     //OneDeptITItemReader <Customer> reader1 = new OneDeptITItemReader<Customer>(); 
     StaxEventItemReader<Customer> reader = new StaxEventItemReader<Customer>(); 
     reader.setResource(new ClassPathResource("xml//customer.xml")); 
     reader.setFragmentRootElementName("customer"); 

     Jaxb2Marshaller marshaller = new org.springframework.oxm.jaxb.Jaxb2Marshaller(); 
     marshaller.setClassesToBeBound(Customer.class); 

     // marshaller.setSchema(new ClassPathResource("xml//company.xsd")); 

     reader.setUnmarshaller(marshaller); 

     return reader; 
    } 

    @Bean 
    public ItemReader<Customer> oneDeptITItemReader(ItemReader<Customer> ir) { 
     OneDeptITItemReader<Customer> odIR = new OneDeptITItemReader<Customer>(); 
     odIR.setDelegate(ir); 
     return odIR; 
    } 
    @Bean 
    public ItemProcessor<Customer, Customer> componentInfoProcessor() { 

     return new CustomerProcessor(); 
    } 

    @Bean 
    public ItemWriter<Object> componentInfoWriter() { 

     return new SqlWritter(); 
    } 
} 

public class OneDeptITItemReader <T> implements ItemReader <Customer>{ 

    ItemReader<Customer> delegate; 

     public ItemReader<Customer> getDelegate() { 
     return delegate; 
    } 

    public void setDelegate(ItemReader<Customer> delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public Customer read() { 
     boolean read = true; 
     Customer item = null; 
     while(read) { 
      try { 
      item = delegate.read(); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      read =false; 
     } 
     read = !"IT".equals(item.getDept()); 
     } 
     return item; 
     } 

} 
+0

は読みに焦点を当てるが、プロセスのフェーズではいけない:カスタム 'ItemProcessorで<顧客、顧客は>' DEPT <>「IT」場合はnullを返すか、DEPTがある場合、オブジェクト自体を返す「IT」 –

+0

に等しいですLuca氏に提案してもらいましたが、以前はこのアプローチについて考えていましたが、XMLファイルは約15 MBと膨大になり、属性値がITの1つのフラグメントしか含まれていないため、数千の顧客フラグメントが解析されずにItemProcessor 。不必要なリソースの消費を避けるためにIT部門で顧客の断片を取得したら、バッチ処理を停止する方法はありますか? –

答えて

0

読み取りが停止する方法nullItemReader.read()から返す。
"IT"部門が見つかると、カスタムItemReaderデリゲートを作成し、読み上げを停止します。

委任を使用する場合は、委任されたリーダーをストリームとして登録して、SBのライフサイクルを管理できるようにする必要があります。 6.5 The Delegate Pattern and Registering with the Step

+0

スニペットを共有してくれてありがとうLucaさん、上記のコードを試しましたが、delegate.read()を呼び出すときにnullポインタの例外が発生しました。 –

+0

自分のコードスニペットを呼び出す前に有効なデリゲートを設定したとします。 –

+0

私は実装の詳細を質問に入れました。アップデート1を参照してください。変更が必要な場合は教えてください。 –

0

私のために以下のスニペットの仕事があります。

読み込みを停止する方法は、ItemReader.read()からnullを返すことです。 "IT"部門が見つかると、カスタムItemReaderデリゲートを作成し、読み込みを停止します。

class OneDeptITItemReader implements ItemReader<Customer> { 
StaxEventItemReader<Customer> delegate; 

public void setDelegate(StaxEventItemReader<Customer> delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public Customer read() { 
    boolean read = true; 
    delegate.open(new ExecutionContext()); 
    Customer item = null; 
    while(read) { 
    item = delegate.read(); 
    read = item != null && !"IT".equals(item.getDept()); 
    } 
    return item; 
    } 
} 
関連する問題