Напишите несколько групп/пакетов с заголовком и трейлером, используя весенний пакет.
Я хочу создать файл с финансовыми транзакциями, подобный следующему формату. В основном транзакции группируются по мерчантам и валютам. Каждая группа имеет отдельный заголовок и трейлер.
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.