【问题标题】:Spring Mail - ImapIdleChannelAdapter Receiving some mails multiple times and some only onceSpring Mail - ImapIdleChannelAdapter 多次接收一些邮件,一些只接收一次
【发布时间】:2020-09-06 23:00:53
【问题描述】:

我正在使用 ImapIdleChannelAdapter 接收传入的邮件。我有一个侦听器配置为获取有关任何传入邮件的通知,该侦听器进一步调用异步方法并将消息处理传递给它。

我面临的问题是它多次收到相同的邮件。我不确定它为什么会这样做。

这是我的配置

@Bean
ImapIdleChannelAdapter mailAdapter() {
    String user = getMail().get("inbound.secure.user");
    String pwd = getMail().get("inbound.secure.pwd");
    String hostname = getMail().get("inbound.secure.host");
    String port = getMail().get("inbound.secure.imap.port");
    String protocol = getMail().get("inbound.secure.imap.protocol");
    String host = protocol + "://" + hostname + ":" + port + "/INBOX";

    ImapMailReceiver mailReceiver = getReceiver(host, user, pwd);

    ImapIdleChannelAdapter mailChannelAdapter = new ImapIdleChannelAdapter(mailReceiver);
    mailChannelAdapter.setAutoStartup(true);
    mailChannelAdapter.setOutputChannel(mailChannel());

    return mailChannelAdapter;
}

private ImapMailReceiver getReceiver(String host, String user, String pwd) {
    ImapMailReceiver jobSeekerMailReceiver = new ImapMailReceiver(host);
    jobSeekerMailReceiver.setSimpleContent(true);
    jobSeekerMailReceiver.setJavaMailProperties(javaMailProperties());
    jobSeekerMailReceiver.setJavaMailAuthenticator(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(user, pwd);
        }
    });
    jobSeekerMailReceiver.afterPropertiesSet();

    jobSeekerMailReceiver.setShouldDeleteMessages(false);
    jobSeekerMailReceiver.setShouldMarkMessagesAsRead(true);

    return jobSeekerMailReceiver;
}

@Bean
public DirectChannel mailChannel() {
    return new DirectChannel();
}

我的听众是

    @MessageEndpoint
public class MailListener {
    private static Logger logger = LoggerFactory.getLogger(MailListener.class);
    private final MailOrganiserService mailOrganiserService;
    @Autowired
    public MailListener(MailOrganiserService mailOrganiserService) {
        this.mailOrganiserService = mailOrganiserService;
    }

    @ServiceActivator(inputChannel = "mailChannel")
    public void handleSecureMessage(Message message) {
            String sender = message.getFrom()[0].toString();
            Address[] recipients = message.getAllRecipients();
            logger.info("handle secure message from {} to {}", sender, recipients);
            this.mailOrganiserService.processIncomingMessageAsync(message);
            logger.info("returning from handing over mail from {} to {}", sender, recipients);
    }
}

我的另一个观察结果是,虽然我已经配置了 ImapIdleChannelAdapter,但我看到了常规日志

attempting to receive mail from folder [INBOX]

这看起来像是轮询行为而不是事件驱动。

我使用的是以下版本

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mail</artifactId>
    <version>5.2.4.RELEASE</version>
  </dependency>

【问题讨论】:

    标签: spring spring-integration imap email


    【解决方案1】:

    ImapMailReceiver 需要定义为@Bean

    否则文件夹将以只读模式打开。

    在 javamail 属性中设置 mail.debug=true 以查看 IMAP 协议交换。

    【讨论】:

    • 谢谢加里。我希望你能对此做出回应:) 我将接收者定义为@Bean 并尝试,但有些邮件只处理一次。我认为拆分可能是大约 60% 的邮件处理一次,40% 的邮件处理多次。我还监控了邮箱,可以看到邮件被标记为已读。
    • mail.debug 永远是你的朋友。