我正在使用Spring Boot 2.2.4-RELEASE和Spring Integration 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
是否在做正确的事情。当然,我具有所有局部变量,并且总是向数据库查询,但是我想知道这是否是正确的方法有人可以给我任何建议吗?
谢谢
天使
编辑-堆栈
这里有关闭的文件夹stacktrace
2020-02-11 18:40:01,688 206505 [task-scheduler-2]警告 o.s.i.mail.ImapIdleChannelAdapter-无法执行IDLE任务。将 尝试在10000毫秒内重新提交。 java.lang.IllegalStateException:“空闲”任务失败。将 重新提交。在 org.springframework.integration.mail.ImapIdleChannelAdapter $ IdleTask.run(ImapIdleChannelAdapter.java:295) 在 org.springframework.integration.mail.ImapIdleChannelAdapter $ ReceivingTask.run(ImapIdleChannelAdapter.java:249) 在 org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) 在 org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) 在 java.base / java.util.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.java:304) 在 java.base / java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) 在 java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:628) 在java.base / java.lang.Thread.run(Thread.java:830)造成原因: javax.mail.MessagingException:文件夹在以下位置关闭 org.springframework.integration.mail.ImapMailReceiver.searchForNewMessages(ImapMailReceiver.java:226) 在 org.springframework.integration.mail.ImapMailReceiver.waitForNewMessages(ImapMailReceiver.java:189) 在 org.springframework.integration.mail.ImapIdleChannelAdapter $ IdleTask.run(ImapIdleChannelAdapter.java:277) ...省略了10个常见框架
答案 0 :(得分:0)
我认为您在调用flowContext.remove(flowId);
时会遇到“文件夹封闭异常”,但是您的MailMessageHandler
中还有一些尝试读取MimeMessage
的过程。
要手动关闭文件夹,您需要访问StaticMessageHeaderAccessor.getCloseableResource(message)
并调用其close()
。