2016-09-26 32 views
0

は、データが存在する場合にのみヘッダをファイルに書き込むタスクを持っています。FlatFileItemWriterデータが存在する場合にのみ、ヘッダを書き込みます。

残念ながらFlatFileItemWriter実装は、バージョン3.0.7で、書き込み処理に関するすべての情報を保存するだけのプライベート・アクセス・フィールドとメソッドや入れ子になったクラスを持っているので、私はちょうど取るとwrite()メソッドを上書きすることはできません。 FlatFileItemWriterのほとんどすべてのコンテンツをコピーして貼り付け、小さな機能を追加する必要があります。

これをSpring Batchでよりエレガントに実現する方法はありますか?

答えて

0

は、最終的にはあまり多くのエレガントました溶液。

解決策はLineAggregatorsを使用することです。FlatFileItemWriterの現在の実装では、このクラスを継承するときに安全に使用できるアプローチの1つと思われます。

私は別々のラインアグリゲータをヘッダーにのみ使用しますが、ソリューションは複数のアグリゲーターを使用するように拡張できます。

私のケースでは、ヘッダーはあらかじめ定義された文字列なので、デフォルトでPassThroughLineAggregatorを使用して、文字列をFlatFileItemWriterに戻します。

public class FlatFileItemWriterWithHeaderOnData extends FlatFileItemWriter { 

    private LineAggregator lineAggregator; 
    private LineAggregator headerLineAggregator = new PassThroughLineAggregator(); 

    private boolean applyHeaderAggregator = true; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     Assert.notNull(headerLineAggregator, "A HeaderLineAggregator must be provided."); 
     super.afterPropertiesSet(); 
    } 

    @Override 
    public void setLineAggregator(LineAggregator lineAggregator) { 
     this.lineAggregator = lineAggregator; 
     super.setLineAggregator(lineAggregator); 
    } 

    public void setHeaderLineAggregator(LineAggregator headerLineAggregator) { 
     this.headerLineAggregator = headerLineAggregator; 
    } 

    @Override 
    public void write(List items) throws Exception { 
     if(applyHeaderAggregator){ 
      LineAggregator initialLineAggregator = lineAggregator; 
      super.setLineAggregator(headerLineAggregator); 
      super.write(getHeaderItems()); 
      super.setLineAggregator(initialLineAggregator); 
      applyHeaderAggregator = false; 
     } 

     super.write(items); 
    } 

    private List<String> getHeaderItems() throws ItemStreamException { 
     // your actual implementation goes here 
     return Arrays.asList("Id,Name,Details"); 
    } 
} 

PS。この解決策は、方法write()が呼び出された場合、いくつかのデータが存在すると仮定しています。

0

私は以下のように考えています。

  1. BeforeStep()(またはタスクレット)データが全く存在しない場合、あなたは、このような「NODATA」は「真」であるとしてフラグを設定します。それ以外の場合は「false」となります

  2. あなたは2つのライターを持っています.1つはヘッダー付きで、もう1つはヘッダーなしです。この場合、ベースライターを親として動作させ、2つのライターがそれを継承するようにすることができます。それらの唯一の違いは、Headerを持つものとHeaderCallBackを持たないものです。フラグの

  3. ベース、あなたは「ヘッダーとライター」や「ヘッダなしのライター」のいずれかに切り替えることができます

おかげで、 Nghiaので

+0

を書く最初の一見のためとして、いくつかの問題があります。 1.私たちは、パラメータとしてのみstepExecutionを持っているので、データが存在します場合は、我々は実際にはまだ知らないbeforeStep 2. FlatFileItemWritersは 'open()'メソッドを呼び出すと2つのファイルを作成します – nahab

+0

私が言っているのは、BeforeStepではデータベースをクエリするか、ロジックがあるかどうかでデータがあるかどうかを調べることができます。 FlatFileItemWriterは、2つのファイルを作成せず、スイッチでも両方でもない。 –

+0

私はSPを実行するときにたくさんのデータを持っています。私はこれを2回したくありません。とにかく、これは私の方法ではないようです。 – nahab

0

あなたはデータがない場合は、ファイルがない、あなたのライター

writer.setShouldDeleteIfEmpty(true);

でこれを試してみてください。 他のケースでは、あなたのヘッダーとアイテム

関連する問題