【问题标题】:Asynchronous mail receiving with Spring Boot and Spring integration使用 Spring Boot 和 Spring 集成的异步邮件接收
【发布时间】:2020-04-29 22:05:59
【问题描述】:

我正在尝试从 gmail 服务器接收电子邮件,然后以某种方式处理它们。所以每次新邮件到达邮件服务器时,我的应用程序都应该下载并处理它,这意味着异步调用其他服务,这些服务将注册为侦听器。

我是 Spring 集成的新手,我不完全了解它是如何工作的,或者它是否正确。

1) 到目前为止,我有这段代码 -- 我能够阅读所有电子邮件,但我不确定它们是否被异步处理或如果是正确的方法?

听力示例类

@Configuration
public class ListeningExample {

    @Bean
    public HeaderMapper<MimeMessage> mailHeaderMapper() {
        return new DefaultMailHeaderMapper();
    }

    @Bean
    public IntegrationFlow imapMailFlow() {    
        IntegrationFlow flow =  IntegrationFlows
                .from(Mail.imapInboundAdapter("imap://user:pwd@imap.gmail.com/INBOX")
                                .userFlag("testSIUserFlag")
                                .javaMailProperties(javaMailProperties()),
                        e -> e.autoStartup(true)
                                .poller(p -> p.fixedDelay(5000)))dostane to detailni zpravy
                .transform(Mail.toStringTransformer())
                .channel(MessageChannels.queue("imapChannel"))
                .get();
        return flow;
     }

    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata defaultPoller() {

        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setTrigger(new PeriodicTrigger(1000));
        return pollerMetadata;
    }
}

MailRecieverService 类

@Service
public class MailRecieverService {

    private List<EmailAction> services;

    @Bean
    @ServiceActivator(inputChannel = "imapChannel")
    public MessageHandler processNewEmail() {
        MessageHandler messageHandler = new MessageHandler() {

            @Override
            public void handleMessage(org.springframework.messaging.Message<?> message) throws MessagingException {
                System.out.println("New email:" + message.toString());

                //Processing emails do with them something..
                for (EmailAction emailAction : services) {
                    emailAction.performAction(null);
                }

            }
        };
        return messageHandler;
    }

}

主类

@SpringBootApplication
@EnableIntegration
public class Main extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Main.class);
    }


    public static void main(String[] args) throws Exception {
        SpringApplicationBuilder builder = new SpringApplicationBuilder(Main.class);
        builder.headless(false).run(args);
    }

}

2) Spring Boot 中是否还可以使用电子邮件帐户移动/删除电子邮件、创建文件夹和执行其他操作,还是我必须自己使用 javax.mail 库? 如果是,你能提供一些例子吗?

【问题讨论】:

  • 据我所知,spring boot 没有提供任何直接的 API 来做这件事,你必须使用邮件库
  • 您是否检查了文档的交易部分?该示例在成功处理消息(事务提交)后移动消息。 docs.spring.io/spring-integration/docs/current/reference/html/…
  • @Pauli 你能提供你的应用程序的完整源代码吗?

标签: java spring spring-boot spring-integration jakarta-mail


【解决方案1】:

您的集成流程是正确的。 IMAP 入站通道适配器本质上是异步的,它产生一个线程来循环新电子邮件。但是,如果您担心for (EmailAction emailAction : services) {,那么您需要考虑自己将这部分设为异步。您绝对可以使用 PublishSubscribeChannelExecutor 以及这些服务的多个订阅者来真正并行处理这些服务中的相同电子邮件。

关于删除、创建和其他电子邮件管理操作的所有其他内容都超出了企业集成模式的范围。因此,没有任何高级 Spring API 可以从应用程序中执行这些操作。考虑直接使用Java Mail API:https://javaee.github.io/javamail/#Project_Documentation

【讨论】:

    【解决方案2】:

    根据文档,ImapIdleChannelAdapter 是异步的。 https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-inbound

    要在消息处理完成后执行操作,您可以将其包装在事务中,并在提交后执行操作:

    在文档的示例中,它将电子邮件移动到另一个文件夹。 https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-tx-sync

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      • 2016-08-31
      • 2015-05-29
      • 2020-01-11
      相关资源
      最近更新 更多