java - 如何在 Spring Mail Integration 中启用 IMAPFolder 读写模式

标签 java spring-boot spring-integration

我在 Spring Boot 应用程序 (v2.1.6.RELEASE) 中使用以下 Java 代码:

@Bean
public IntegrationFlow mailListener() {

    SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
        SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"), new FlagTerm(new Flags(Flags.Flag.SEEN), false));
        return search;
    };

    return IntegrationFlows.from(Mail.imapInboundAdapter("imaps://usr:pwd@imap.host.com/INBOX").searchTermStrategy(searchTermStrategy).shouldMarkMessagesAsRead(true).get(),
            e -> e.poller(Pollers.fixedRate(5000).maxMessagesPerPoll(1)))
            .<Message>handle((payload, header) -> logMail(payload))
            .get();
}

但是当有匹配的消息时,这会引发异常com.sun.mail.iap.CommandFailedException: A7 NO Command returned in Invalid state.。这似乎是 IMAP 文件夹默认设置为只读的问题。

AbstractMailReceiver 类中有一个 onInit protected 方法,该方法以读写模式打开文件夹。我有tried调用 ImapMailReceiver.afterPropertiesSet() 最终调用 onInit 方法,但这给了我一个外部“接收器”...无法修改。:

@Bean
private ImapMailReceiver receiver() {
    ImapMailReceiver receiver = new ImapMailReceiver("...URL...");
    receiver.afterPropertiesSet();
    //receiver.setJavaMailProperties(javaMailProperties);
    return receiver;
}

有人可以指导我如何将文件夹设置为读写模式吗?

P.S. 在纯 Java 代码中,我可以使用 inbox.open(Folder.READ_WRITE) 设置相同的内容,并且这有效。

编辑1

如果我使用这样的代码:

@Bean
public IntegrationFlow mailListener() {

    SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
        SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
                new FlagTerm(new Flags(Flags.Flag.SEEN), false));
        return search;
    };

    return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()))
            .log()
            .get();
}

@Bean
public ImapMailReceiver receiver() {
    return new ImapMailReceiver(IMAP_URL);
}

我收到以下错误:

Caused by: java.lang.IllegalArgumentException: No poller has been defined for channel-adapter 'mailListener.org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0', and no default poller is available within the context.
    at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean.initializeAdapter(SourcePollingChannelAdapterFactoryBean.java:186) ~[spring-integration-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean.afterPropertiesSet(SourcePollingChannelAdapterFactoryBean.java:144) ~[spring-integration-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    ... 26 common frames omitted

编辑2

如果我使用如下代码:

@Bean
public IntegrationFlow mailListener() {

    SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
        SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
                new FlagTerm(new Flags(Flags.Flag.SEEN), false));
        return search;
    };

    return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()).searchTermStrategy(searchTermStrategy).shouldMarkMessagesAsRead(true).get(),
            e -> e.poller(Pollers.fixedRate(5000).maxMessagesPerPoll(1)))
            .<Message>handle((payload, header) -> logMail(payload))
            .get();
}

@Bean
public ImapMailReceiver receiver() {
    return new ImapMailReceiver(IMAP_URL);
}

我收到以下错误:

Caused by: java.lang.IllegalStateException: An external 'receiver' [imaps://.../INBOX] can't be modified.
    at org.springframework.util.Assert.state(Assert.java:94) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.integration.mail.dsl.MailInboundChannelAdapterSpec.assertReceiver(MailInboundChannelAdapterSpec.java:85) ~[spring-integration-mail-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.integration.mail.dsl.ImapMailInboundChannelAdapterSpec.searchTermStrategy(ImapMailInboundChannelAdapterSpec.java:51) ~[spring-integration-mail-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at com.xxx.emailapp.InboundEmailConfig.mailListener(InboundEmailConfig.java:33) ~[classes/:na]
    at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59.CGLIB$mailListener$1(<generated>) ~[classes/:na]
    at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59$$FastClassBySpringCGLIB$$8ee22ea2.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59.mailListener(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    ... 19 common frames omitted

最佳答案

声明显式接收器 bean 有效

@Bean
public IntegrationFlow mailListener() {

    SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
        SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
                new FlagTerm(new Flags(Flags.Flag.SEEN), false));
        return search;
    };

    return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()))
            .log()
            .get();
}

@Bean
public ImapMailReceiver receiver() {
    return new ImapMailReceiver("imaps://usr:pwd@imap.host.com/INBOX");
}

编辑

您不得在接收器规范上调用get();框架需要引用规范本身才能正确初始化 bean。

关于java - 如何在 Spring Mail Integration 中启用 IMAPFolder 读写模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57126841/

相关文章:

java - 2个线程如何在notifyAll之后获得锁?

java - 交换方法在 C# 中如何在内存级别工作?

java - WicketTester 与 Hibernate

java - 有人可以帮助我在 rest-api 中使用文本文件吗?

使用 Spring Boot 时出现 Spring 批处理范围问题

java - spring boot 使用 kafka 进行分布式处理

java - 没有 Transformer 的 Spring TCP 客户端

spring - Kafka Connect 与 Spring 框架

java - 使用正则表达式将字符串拆分为不同类型的数组

spring-boot - 如何在 spring-boot web 客户端中发送请求正文?