Напишите несколько групп/пакетов с заголовком и трейлером, используя весенний пакет.

Я хочу создать файл с финансовыми транзакциями, подобный следующему формату. В основном транзакции группируются по мерчантам и валютам. Каждая группа имеет отдельный заголовок и трейлер.

      FILE_HEADER
       MERCHANT_AND_CURRENCY_HEADER
         TRANSACTION_WITH_AMOUNT_AND_SAME_CURRENCY_INDICATED_IN_HEADER
       MERCHANT_FOOTER_WITH_COUNTER_AND_TOTAL_AMOUNT_OF_TRANSACTIONS_FOR_CURRENT_CURRENCY
       MERCHANT_AND_CURRENCY_HEADER
         TRANSACTION_WITH_AMOUNT_AND_SAME_CURRENCY_INDICATED_IN_HEADER
       MERCHANT_FOOTER_WITH_COUNTER_AND_TOTAL_AMOUNT_OF_TRANSACTIONS_FOR_CURRENT_CURRENCY
       MERCHANT_AND_CURRENCY_HEADER
         TRANSACTION_WITH_AMOUNT_AND_SAME_CURRENCY_INDICATED_IN_HEADER
       MERCHANT_FOOTER_WITH_COUNTER_AND_TOTAL_AMOUNT_OF_TRANSACTIONS_FOR_CURRENT_CURRENCY
FILE_FOOTER

сейчас я загружаю транзакции из базы данных, используя следующий ItemReader

      @Bean
    @StepScope
    public RepositoryItemReader<EvryTransactionFileEod> transactionRepositoryReader(EvryTransactionFileEodRepository evryTransactionFileEodRepository
            , @Value("#{jobParameters[" + PARAM_CUTOFF_DATE_TIME + "]}") LocalDateTime cutoffDate
            , @Value("#{stepExecution.jobExecution.id}") long batchId){
        try {
            return new RepositoryItemReaderBuilder<EvryTransactionFileEod>()
                    .methodName("findByBatchId").name("transactionFileReader")
                    .arguments(Arrays.asList(batchId))
                    .sorts(Map.of("merchantId", Sort.Direction.ASC,
                            "transactionCurrencyCode", Sort.Direction.ASC, "trxnNo", Sort.Direction.ASC))
                    .repository(evryTransactionFileEodRepository)
                    .pageSize(FG_CHUNK_SIZE)
                    .build();
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

затем в ItemProcessor поместите элементы в список с одинаковым продавцом и валютой. если текущий элемент отличается, верните EodFileGroup следующим образом

      @Override
    public EodFileGroup process(EvryTransactionFileEod item) {
        try {

            TransactionDto transactionDto = new TransactionDto();
            transactionDto.setMsgType(item.getMsgType());
            ...
            ...
            transactionDto.setP63(item.getP63());
            incrementCountsInContext(item);
            if(transactionDtoList.isEmpty()){
                merchantCurrency = transactionDto.getMerchantId()+transactionDto.getTransactionCurrencyCode();
                transactionDtoList.add(transactionDto);
                return null;
            }
            else if((item.getMerchantId()+item.getTransactionCurrencyCode()).equals(merchantCurrency)){
                transactionDtoList.add(transactionDto);
                return null;
            }
            else
            {
                EodFileGroup eodFileGroup = new EodFileGroup();
                eodFileGroup.setTransactions(List.copyOf(transactionDtoList));
                eodFileGroup.setHeader("---H---");
                eodFileGroup.setTrailer("---T---");
                transactionDtoList.clear();
                //add new merchantCurrency dto s
                merchantCurrency = item.getMerchantId()+item.getTransactionCurrencyCode();
                transactionDtoList.add(transactionDto);
                return eodFileGroup;
            }
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

Еодфилегрупп

      public class EodFileGroup {
    private String header;
    private List<TransactionDto> transactions;
    private String trailer;
}

ItemWriter ожидает объекты EodFileGroup и записывает в файл

       @Bean
    @StepScope
    public ItemWriter<EodFileGroup> eodFileDtoItemWriter(
            @Value("#{jobParameters[" + PARAM_CURRENT_DATE_TIME + "]}") LocalDateTime currentDate){
        try{
            String folderPath = FileUtils.getUserDirectoryPath();
            String dateTime = GeneralUtils.formatDate("yyyyMMdd_HHmmss", currentDate);
            String fileName = fileNamePrefix + dateTime;

            GroupItemWriter groupItemWriter = new GroupItemWriter(folderPath + File.separator + fileName);
return groupItemWriter;
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

метод записи в GroupItemWriter

       @Override
    public void write(Chunk<? extends EodFileGroup> groups) throws Exception {
        try (Writer writer = new BufferedWriter(new FileWriter(outputFile))) {
            for (EodFileGroup group : groups) {
                // Write the header to the file
                writer.write(group.getHeader());

                // Write the transactions to the file
                for (TransactionDto transaction : group.getTransactions()) {
                    writeTransaction(writer, transaction);
                }

                // Write the trailer to the file
                writer.write(group.getTrailer());
                //writeTrailer(writer);
            }
        } catch (IOException e) {
            throw new Exception("Error writing to the output file", e);
        }
    }

Есть ли лучший подход, чем этот, для достижения моего требования с использованием весенней партии? Также в приведенном выше решении у меня возникла проблема с идентификацией последнего элемента в методе процесса ItemProcessor, чтобы вернуть объект EodFileGroup.

0 ответов

Другие вопросы по тегам