2017-04-07 16 views
1

私は現在、私が間違って行った設定を診断しようとしているアプリケーションを持っていますが、なぜ非常に外で動作していないのか判断できない特定の状況。カスタムItemReaderからアクセスしたときにFlatFileItemReaderをキャストできません

最初に私が使用しているコード。

Configuration.java

@EnableBatchProcessing 
@SpringBootApplication(scanBasePackages="com.lcbo") 
@EnableIntegration 
public class COnfig { 

    @Autowired 
    private JobBuilderFactory jobBuilderFactory; 

    @Autowired 
    private StepBuilderFactory stepBuilderFactory; 

    @Autowired 
    private LCBOInventoryTrackerProperties inventoryTrackerProperties; 

    @Bean 
    public Job processLCBOInventory(@Qualifier("getLCBOStoreDataStep") final Step getLCBOStoreDataStep) { 
     return jobBuilderFactory 
       .get("processLCBOInventory") 
       .incrementer(new RunIdIncrementer()) 
       .start(getLCBOStoreDataStep) 
       .build(); 

    } 

    /** 
    * This tasklet downloads the .zip file, unzips, and saves it in the appropriate folder under resources. 
    * Execute at 6am daily 
    * 
    //  * @param AcquireDataFileTasklet acquireDataFiles 
    * @return Step - returns Step status; either SUCCESS or FAILURE 
    */ 

    @Bean 
    public Step getCurrentLCBODataStep(final AcquireDataFileTasklet acquireDataFiles, 
             final ExecutionContextPromotionListener listener) { 
     return stepBuilderFactory 
       .get("getCurrentLCBODataStep") 
       .tasklet(acquireDataFiles) 
       .allowStartIfComplete(true) 
       .listener(listener) 
       .build(); 
    } 

    @Bean 
    public Step getLCBOStoreDataStep(final LCBOStoreReader lcboStoreReader, 
            final LCBOStoreWriter lcboStoreWriter) { 

     return stepBuilderFactory 
       .get("getLCBOStoreDataStep") 
       .<LCBOStore, LCBOStore>chunk(inventoryTrackerProperties.getDefaults().getChunkSize()) 
       .reader(lcboStoreReader) 
       .writer(lcboStoreWriter) 
       .build(); 
    } 
} 

リーダクラス

@Component 
public class LCBOStoreReader extends AbstractLCBOReader implements ItemReader, InterstepDataRetriever { 

    private static final Logger log = LoggerFactory.getLogger(LCBOStoreReader.class); 

    @Override 
    public ItemReader<LCBOStore> read() throws UnexpectedInputException, ParseException, NonTransientResourceException { 
     Class<LCBOStore> classType = LCBOStore.class; 

     return createCSVReader(classType, currentCSVFilePath, inventoryTrackerProperties.getLCBOFilPropertiess().getStores()); 
    } 
/* 
    @Override 
    public void beforeStep(final StepExecution stepExecution) { 
     JobExecution jobExecution = stepExecution.getJobExecution(); 
     ExecutionContext jobContext = jobExecution.getExecutionContext(); 
     this.currentWorkingDate = (String) jobContext.get("currentWorkingDateKey"); 
    } 
*/ 
    @Override 
    public void retrieveInterstepDataFromJobContext(final ExecutionContext jobContext) { 
     this.currentCSVFilePath = (String) jobContext.get("currentCSVFilePathKey"); 
    } 
} 

及び(FlatFileItemReaderセットアップは、複数のリーダによって使用されているため)、それが拡張するクラスは

public abstract class AbstractLCBOReader { 

    @Autowired 
    protected LCBOInventoryTrackerProperties inventoryTrackerProperties; 

    protected String currentCSVFilePathKey; 
    protected String currentCSVFilePath; 

    private static final Logger log = LoggerFactory.getLogger(AbstractLCBOReader.class); 

    protected <T> ItemReader<T> createCSVReader(final Class<T> classType, 
               final String currentCSVFilePath, 
               final LCBOFileDetailsProperties properties) { 

     FlatFileItemReader<T> reader = new FlatFileItemReader<>(); 
     // Skip a line to ignore the header information in these files 
     reader.setLinesToSkip(properties.getNumberOfLinesToSkipInFile()); 
     reader.setResource(new FileSystemResource(currentCSVFilePath + File.separator + properties.getFileName())); 
     reader.setLineMapper(createLineMapper(classType, properties)); 
     reader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy()); 
     reader.setEncoding("utf8"); 

     return reader; 
    } 

    private <T> LineMapper<T> createLineMapper(final Class<T> classType, final LCBOFileProperties.LCBOFileDetailsProperties properties) { 
     DefaultLineMapper<T> lineMapper = new DefaultLineMapper<>(); 
     lineMapper.setLineTokenizer(createLineTokenizer(properties)); 
     lineMapper.setFieldSetMapper(createFieldSetMapper(classType)); 

     return lineMapper; 
    } 

    private <T> FieldSetMapper<T> createFieldSetMapper(final Class<T> classType) { 
     BeanWrapperFieldSetMapper<T> fieldSetMapper = new BeanWrapperFieldSetMapper<>(); 
     fieldSetMapper.setTargetType(classType); 

     return fieldSetMapper; 
    } 

    private LineTokenizer createLineTokenizer(final LCBOFileProperties.LCBOFileDetailsProperties properties) { 
     LCBOFileProperties.Column[] columns = properties.getColumns(); 
     int[] columnIndexes = new int[columns.length]; 
     String[] columnNames = new String[columns.length]; 

     // populating the columnIndexes 
     for (int i = 0; i < columns.length; i++) { 
      columnIndexes[i] = columns[i].getColumnIndex(); 
      columnNames[i] = columns[i].getColumnName(); 
     } 

     DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); 
     lineTokenizer.setIncludedFields(columnIndexes); 
     lineTokenizer.setNames(columnNames); 
     lineTokenizer.setDelimiter(","); 
     lineTokenizer.setQuoteCharacter('"'); 

     return lineTokenizer; 
    } 
} 

これを実行するとエラーが発生しますオブジェクトをFlatFileItemreaderからcreateCSVReaderの最初のパラメータとして渡されたオブジェクトにキャストすることはできません。ここに例があります。

public class LCBOStore { 

    private Long id; 
    private String addressLineOne; 
    private String addressLineTwo; 
    private String city; 
    private String postalCode; 
    private String latitude; 
    private String longitude; 
    private String updatedAt; //Convert to Date 

    public LCBOStore(final Long id, final String addressLineOne, final String addressLineTwo, final String city, 
        final String postalCode, final String latitude, final String longitude, final String updatedAt) { 
     this.id = id; 
     this.addressLineOne = addressLineOne; 
     this.addressLineTwo = addressLineTwo; 
     this.city = city; 
     this.postalCode = postalCode; 
     this.latitude = latitude; 
     this.longitude = longitude; 
     this.updatedAt = updatedAt; 
    } 

    public Long getId() { 
     return id; 
    } 

    public String getAddressLineOne() { 
     return addressLineOne; 
    } 

    public String getAddressLineTwo() { 
     return addressLineTwo; 
    } 

    public String getCity() { 
     return city; 
    } 

    public String getPostalCode() { 
     return postalCode; 
    } 

    public String getLatitude() { 
     return latitude; 
    } 

    public String getLongitude() { 
     return longitude; 
    } 

    public String getUpdatedAt() { 
     return updatedAt; 
    } 

    public void setId(final Long id) { 
     this.id = id; 
    } 

    public void setAddressLineOne(final String addressLineOne) { 
     this.addressLineOne = addressLineOne; 
    } 

    public void setAddressLineTwo(final String addressLineTwo) { 
     this.addressLineTwo = addressLineTwo; 
    } 

    public void setCity(final String city) { 
     this.city = city; 
    } 

    public void setPostalCode(final String postalCode) { 
     this.postalCode = postalCode; 
    } 

    public void setLatitude(final String latitude) { 
     this.latitude = latitude; 
    } 

    public void setLongitude(final String longitude) { 
     this.longitude = longitude; 
    } 

    public void setUpdatedAt(final String updatedAt) { 
     this.updatedAt = updatedAt; 
    } 

    @Override 
    public String toString() { 
     return "StoreDBModel [id=" + id + ", addressLineOne=" + addressLineOne + ", city=" + city 
       + ", postalCode=" + postalCode + ", latitude=" + latitude + ", longitude=" 
       + longitude + ", updatedAt=" + updatedAt + "]"; 
    } 
} 

は今、私はそれが正常に動作し、カスタムのリーダークラスのコンストラクタにcreateCSVReaderに存在するFlatFileItemReaderモードを移動したり、それが設定ファイルにありますので、それを持っている場合。しかし、私はどのようにそれらの構成でジョブとステップコンテキストで作業するのか分かりませんでした(コンストラクタは私がテストから見えるstepとjobContextにアクセスする前に実行されます。 )。少なくとも私にとっては、コンストラクタに埋め込まれていない独自のファイルにReaderコードを持つ方がきれいに見えます。

したがって、一言で言えば、自分のリーダークラスで動作させると、これを修正する方法はありますか?私はこれを間違ってやって、悪い習慣を使っていますか?多分2つの組み合わせ?行方不明のものがあれば、遠慮なく私が明確にしようとします。

+0

あなたのリーダーは 'ItemReader 'を返します。委任先のアイテムリーダーでreadメソッドを呼び出し、 'YourObject'を返します。 readメソッドの全目的は、実際のオブジェクトを元のアイテムリーダーではなく返すことです。 –

+0

'LCBOStoreReader.read()'は 'LCBOStore'を返しますが、' ItemReader'は返しません... – OhadR

+0

何か簡単なことが分かっていて、読み込み関数はルートcsvParserクラスのためだけに機能していました。自動的に読み込みを呼び出す方法。いずれにせよ、頭のおかげで、それは私に解決策を得るのを助けた。 – canadiancreed

答えて

0

私は、答えの中には、コメントの中のいくつかの助けを借りて、非常に簡単であることがわかりました。ここに私の解決策があります。

まず、手動で読み取り呼び出しを行う抽象クラスcreateCSVWriterメソッドに

**protected <T> T** createCSVReader(final Class<T> classType, 
           final String currentCSVFilePath, 
           final LCBOFileDetailsProperties properties) throws Exception { 

    FlatFileItemReader<T> reader = new FlatFileItemReader<>(); 
    // Skip a line to ignore the header information in these files 
    reader.setLinesToSkip(properties.getNumberOfLinesToSkipInFile()); 
    reader.setResource(new FileSystemResource(currentCSVFilePath + File.separator + properties.getFileName())); 
    reader.setLineMapper(createLineMapper(classType, properties)); 
    reader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy()); 
    reader.setEncoding("utf8"); 

    **return reader.read();** 
} 

を太字コードを追加しますが、それはあなたのリーダークラスのために必要な、より多くを返す防ぐことができます。その後、読者クラスで次のように編集します

@Override 
public **LCBOStore** read() throws **Exception**, UnexpectedInputException, ParseException, NonTransientResourceException { 
    Class<LCBOStore> classType = LCBOStore.class; 

    return createCSVReader(classType, currentCSVFilePath, inventoryTrackerProperties.getLCBOFilPropertiess().getStores()); 
} 

これはあなたが作成したオブジェクトを返すため、解決されました。

関連する問題