如何在Spring Mail集成中启用IMAPFolder读写模式



我在我的 Spring 引导应用程序 (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 received in Invalid state.。这似乎是默认情况下将IMAP文件夹设置为只读的问题。

AbstractMailReceiver类中有一个受onInit保护的方法,该方法以读写模式打开文件夹。我试图调用最终调用onInit方法的ImapMailReceiver.afterPropertiesSet(),但这给了我An external 'receiver' ... can't be modified.

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

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

附言在纯 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。

最新更新