imap 邮件接收器

问题描述 投票:0回答:1

我正在使用 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
,但我有一些问题。

  1. 通过我使用时的文档
    .autoCloseFolder(false)
    我读到:

配置为 false 时,文件夹不会自动关闭 一个取。目标应用程序有责任关闭它 使用 IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE 标头 来自此通道适配器生成的消息。

我不知道我是否应该做什么以及应该做什么来告诉框架关闭文件夹

  1. 有时我会收到错误文件夹关闭异常。我无法理解原因
  2. 我不确定使用单例组件作为
    msgHandler
    我是否在做正确的事情。当然,我有所有局部变量,并且我总是向数据库进行查询,但我想知道这是否是正确的方法

这里是关闭的文件夹stacktrace

2020-02-11 18:40:01,688 206505 [任务调度程序-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$$$捕获(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个常见框架

有人有什么建议吗?

spring spring-boot spring-integration spring-integration-dsl
1个回答
0
投票

我认为当您调用该

flowContext.remove(flowId);
时,您会遇到“文件夹关闭异常”,但是您的
MailMessageHandler
尝试读取
MimeMessage
时还有一些过程。

要手动关闭文件夹,您需要访问

StaticMessageHeaderAccessor.getCloseableResource(message)
并调用其
close()

© www.soinside.com 2019 - 2024. All rights reserved.