#java #spring #spring-batch #itemprocessor
Вопрос:
У меня есть следующий ItemProcessor, мне нужно знать, является ли элемент последним, который отправляет читатель. Возможно ли это?
Поток-это:
ItemReader
— считывание строк из базы данных (ожидаемые миллионы строк)ItemProcessor
— выполните некоторые проверки в каждой строке, отправьте в веб-сервис и выполните дополнительные проверки с ответом веб-сервиса.ItemWriter
— запишите в базу данных ошибки при проверке и измените статус строки.
Другим возможным решением было бы средство чтения элементов для отправки списка Line
с размером NUMBER_OF_LINES_TO_CALL_WEBSERVICE
, но я не смог найти примеров того, как его изменить JpaPagingItemReader
.
@Override
public List<Line> process(Line line) {
lineList.add(line);
if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {
callWs(lineList);
return lineList; // goes to ItemWriter to write the response from ws in database
}
if( /* TODO if last line */) {
callWs(lineList);
return lineList;
}
return null;
}
private void callWs(List<Line> lineList){
...
//Get response from webservice and add info to lines
}
@Override
public void afterChunk(ChunkContext chunkContext) {
if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {
lineList.clear();
}
}
Читатель-это JpaPagingItemReader
:
@Bean
@StepScope
public JpaPagingItemReader<Line> itemReader(@Qualifier("EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
String queryStr = "select l from Line l" ;
return new JpaPagingItemReaderBuilder<Linha>()
.name("lineReader")
.entityManagerFactory(entityManagerFactory)
.queryString(queryStr)
.pageSize(PAGE_SIZE)
.build();
}
Комментарии:
1. Зачем тебе это нужно? Можете ли вы описать, чего вы пытаетесь достичь, не обращаясь к весенней партии? Каков ввод/вывод вашего шага/задания? Есть способ сделать это, но это зависит от ответов на эти вопросы.
2. Я хочу сгруппировать строки в списке из 100 элементов для отправки в веб-сервис, и когда последний элемент отправляется в процессор, остальные строки отправляются в веб-сервис.
Ответ №1:
Я хочу сгруппировать строки в списке из 100 элементов для отправки в веб-сервис, и когда последний элемент отправляется в процессор, остальные строки отправляются в веб-сервис.
Вы можете использовать шаг, ориентированный на фрагмент, с размером фрагмента 100. Этот шаг выполнит буферизацию за вас, и первый пункт процесса, в котором у вас будет доступ к списку элементов, находится в разделе ItemWriteListener#beforeWrite(List items)
. Таким образом, вы можете либо использовать этот прослушиватель для выполнения вызова веб-службы, либо сделать это ItemWriter
самостоятельно (если это единственная write
операция, которую вам нужно выполнить).
Как только у вас будет список товаров, вы сможете делать с ним все, что захотите (т. Е. проверять последний товар, фильтровать первые 99 товаров и отправлять их в веб-службу и т. Д.).
Комментарии:
1. Это не единственная
write
операция. ТоItemWriter
запишет ошибки в базу данных. Может быть, лучшим подходом было бы изменитьItemReader
отправку списка из 100 элементов, вы согласны? Но при таком подходе мне нужна помощь , чтобы изменитьItemReader
, может быть, я смогу создать конкретный вопрос для этого.2. В этом случае вы можете использовать
ItemWriteListener#beforeWrite
для выполнения вызова веб-службы иItemWriter
для записи в базу данных. Я не вижу необходимости изменять читателя, вы должны использовать фрагментацию/буферизацию элементов, предоставляемых пошаговой реализацией.3. Спасибо, я об этом не знал
ItemWriteListener
. Такой подход выглядит хорошо