是否可以在处理邮件后设置 spring 集成邮件入站适配器标志?

Is there a possibility to set spring integration mail inbound adapter flags after handling the message?

简介:
我们目前正在使用 spring 邮件集成来接收和发送电子邮件,如果没有异常(例如与交换服务器或数据库的连接错误),它可以正常工作。

这些邮件作为消息传入,并传递给处理程序方法,该方法将 MimeMessage 解析为自定义邮件数据对象。 JPA 将这些实体保存为我们数据库的最后一步。

Question/Problem:
如果数据库已关闭或由于任何其他原因无法处理邮件,则会出现问题,因为一旦邮件传递给处理程序,IntegrationFlow 仍会将其标记为 /SEEN。

将此标志设置为 false 不会解决我们的问题,因为如果邮件被正确处理和保存,我们希望 Spring 设置 /SEEN 标志

shouldMarkMessagesAsRead(false) 

正在搜索:
是否有可能在成功将邮件保存到数据库后设置标志?
我们想在导致错误的原因被修复后再次处理失败的电子邮件,只要 Spring 将它们标记为 /SEEN 无论结果如何,这都不会起作用。

参考:
消息传入并传递给处理程序,该处理程序将解析邮件并执行 CRUD-Repository save(mailDAO) 方法。 handleMimeMessage() 或多或少只是一个映射器。

@Bean
fun imapIdleFlow(imapProperties: ImapProperties): IntegrationFlow {
    imapProperties.username.let { URLEncoder.encode(it, charset) }
    return IntegrationFlows
        .from(
            Mail.imapIdleAdapter(
                ImapMailReceiver("imap://${imapProperties.username}:${imapProperties.password}@${imapProperties.host}/Inbox")
                    .apply {
                        setSimpleContent(true)
                        setJavaMailProperties(imapProperties.properties.toProperties())
                    })
                .autoStartup(true)
                .shouldReconnectAutomatically(true)
        )
        .handle(this::handleMimeMessage)
        .get()
}

是否可以在您需要第二次访问交换时在同一流中标记邮件,或者我是否需要第二个流来获取和标记相同的邮件?

我认为可以使用事务同步之类的东西:https://docs.spring.io/spring-integration/reference/html/mail.html#mail-tx-sync

因此,您将那个 Mail.imapIdleAdapter 上的 transactional(TransactionManager transactionManager) 设置为 JpaTransactionManager 以从此 IMAP 空闲通道适配器开始事务并将其传播到您的 handleMimeMessage()那些 JPA 保存。

加上你补充:

/**
 * Configure a {@link TransactionSynchronizationFactory}. Usually used to synchronize
 * message deletion with some external transaction manager.
 * @param transactionSynchronizationFactory the transactionSynchronizationFactory.
 * @return the spec.
 */
public ImapIdleChannelAdapterSpec transactionSynchronizationFactory(
        TransactionSynchronizationFactory transactionSynchronizationFactory) {

对上述事务的提交和回滚作出反应。

带有一些 TransactionSynchronizationProcessor impl 的 DefaultTransactionSynchronizationFactory 可以为您提供所需的行为,您可以从提供的 IntegrationResourceHolder 中获取 Message 及其有效负载并执行类似message.setFlag(Flag.SEEN, true);MimeMessage.

您可以考虑使用文档中提到的 ExpressionEvaluatingTransactionSynchronizationProcessor.

为避免重新打开文件夹,您可以考虑使用带有 false 选项的 public ImapIdleChannelAdapterSpec autoCloseFolder(boolean autoCloseFolder) {。您需要考虑以 TX sync impl 或其他方式关闭它。