Я использую весеннюю загрузку 2.2.4-RELEASE и интеграцию пружин 5.2.3, и я использую IntegrationFlow и DSL, потому что мне нужно настроить несколько серверов IMAP.
Итак, я написал этот код:
String flowId = MAIL_IN_FLOW_ID_PREFIX+cpd.getIndirizzoMail();
if( flowContext.getRegistrationById(flowId) != null ) {
flowContext.remove(flowId);
}
ImapIdleChannelAdapterSpec imapIdleChannelAdapterSpec = Mail.imapIdleAdapter(connectionUrl.toString())
.javaMailProperties(javaMailProperties)
.shouldDeleteMessages(deleteMessages)
.shouldMarkMessagesAsRead(markMessagesRead)
.autoStartup(true)
.autoCloseFolder(false)
.id(confMailIn.getHost()+"_adapter")
.selector(selectFunction);
IntegrationFlow flowIdle = IntegrationFlows.from(imapIdleChannelAdapterSpec)
.handle(msgHandler)
.get();
flowContext.registration(flowIdle).id(flowId).register();
, где msgHandler
равно
@Component
public class MailMessageHandler implements MessageHandler {
private static final Logger logger = LoggerFactory.getLogger(MailMessageHandler.class.getName());
@Autowired
private IConfigCasPostaleSvc ccps;
@Autowired
private IGestioneMailSvc gestioneMailSvc;
@Override
public void handleMessage(Message<?> message) throws MessagingException {
MimeMessage mimeMessage = (MimeMessage) message.getPayload();
if( logger.isDebugEnabled() ) {
try {
mimeMessage.getAllHeaders().asIterator().forEachRemaining(header->{
logger.debug("Header name {} header value {}", header.getName(), header.getValue());
});
} catch (javax.mail.MessagingException e) {
logger.error("Errore nella lettura degli header", e);
}
}
try {
//Recupero i dati del messaggio
MimeMessageParser parser = new MimeMessageParser(mimeMessage);
parser = parser.parse();
String mailId = mimeMessage.getMessageID();
String oggettoMail = parser.getSubject();
Date receivedDate = mimeMessage.getReceivedDate();
List<DataSource> allegatiMail = parser.getAttachmentList();
String corpoMail = parser.getHtmlContent();
if( !StringUtils.hasText(corpoMail) ) {
if( logger.isDebugEnabled() ) {
logger.debug("Nessun contenuto HTML nella mail; recupero il contenuto plain/text");
}
corpoMail = parser.getPlainContent();
}
MailInDto datiMail = new MailInDto();
datiMail.setAllegatiMail(allegatiMail);
datiMail.setIdMail(mailId);
datiMail.setOggettoMail(oggettoMail);
datiMail.setDataRicezioneMail(receivedDate);
datiMail.setAllegatiMail(allegatiMail);
datiMail.setCorpoMail(corpoMail);
List<Address> destinatari = parser.getTo();
for (Address to:destinatari) {
String destinatario = to.toString();
if( to instanceof InternetAddress ){
destinatario = ((InternetAddress)to).getAddress();
}
//Considero solo i destinatari che sono censiti nelle nostre tabelle
Optional<ConfigurazioneCasellaPostaleDto> configurazioneCasellaPostale = ccps.getConfigurazioneCasellaPostale(destinatario);
if( configurazioneCasellaPostale.isPresent() ) {
ConfigurazioneCasellaPostaleDto ccpd = configurazioneCasellaPostale.get();
//Indico l'UUID del documentale che contiene tutti i messaggi mail della casella postale
datiMail.setParentIdFolder(ccpd.getCasellaPostale().getIdFolderDocumentale());
//Posso salvare
datiMail.setIdCasellaPostale(ccpd.getCasellaPostale().getPk());
this.gestioneMailSvc.storeReceivedMail(datiMail, parser);
}else {
if( logger.isDebugEnabled() ) {
logger.debug("Nessuna configurazione casella postale trovata per il destinatario {}", destinatario);
}
}
}
}catch (Exception e) {
throw new MessagingException("Errore nella gestione del messaggio "+message, e);
}
}
}
Установив .autoCloseFolder(false)
Я могу обработать MimeMessage
в компоненте обработчика, но у меня есть несколько вопросов.
- В документации, когда я использую
.autoCloseFolder(false)
, я читаю:
При значении false папка не закрывается автоматически после извлечения. Это целевое приложение несет ответственность за его закрытие с помощью заголовка IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE из сообщения, генерируемого этим канальным адаптером.
Я не могу понять, нужно ли и что я должен делать для того, чтобы сообщить структуре закрыть папку
Иногда я получаю сообщение об ошибке закрытия папки исключения. Я не могу понять причину Я не уверен, что при использовании одноэлементного компонента, как
msgHandler
, я поступаю правильно. Конечно, у меня есть все локальные переменные, и я всегда делаю запрос к БД, но мне интересно, если это правильный подход
Может кто-нибудь дать мне какое-нибудь предложение?
Спасибо
Angelo
РЕДАКТИРОВАТЬ - STACKTRACE
Здесь находится трассировка стека закрытой папки
2020-02-11 18: 40: 01,688 206505 [task-scheduler-2] WARN osimail.ImapIdleChannelAdapter - Не удалось выполнить задачу IDLE. Попытка повторной отправки через 10000 миллисекунд. java .lang.IllegalStateException: сбой в задаче «ожидания». Повторно представим. в org.springframework.integration.mail.ImapIdleChannelAdapter $ IdleTask.run (ImapIdleChannelAdapter. java: 295) в org.springframework.integration.mail.ImapIdleChannelAdapter $ ReceivingTask.runnel * 24p. .scheduling.support. .concurrent.Executors $ RunnableAdapter.call (Executors. java: 515) в java .base / java .util.concurrent.FutureTask.run $$$ capture (FutureTask. java: 264) в java .base / java .util.concurrent.FutureTask.run (FutureTask. java) в java .base / java .util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run (ScheduledThreadPoolExecutor. 304) в java .base / java .util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor. java: 1128) в java .base / java .util.concurrent.ThreadPoolExecutor $ Worker.run ( Автошоу adPoolExecutor. java: 628) в java .base / java .lang.Thread.run (Thread. java: 830) Причина: javax.mail.MessagingException: папка закрывается на org.springframework. integra.mail.ImapMailReceiver.searchForNewMessages (ImapMailReceiver. java: 226) в org.springframework.integration.mail.ImapMailReceiver.waitForNewMessages (ImapMailReceiver. java: 189) в org.springframenel.kash.Ill.Igration. run (ImapIdleChannelAdapter. java: 277) ... пропущено 10 общих кадров