Class 尝试使用 spring 集成消息负载移动电子邮件时出现异常

Class exception when trying to move a email using the spring integration message payload

您好,我已经如下配置了默认过滤器,如果某些电子邮件具有特定主题或发件人地址,我会尝试使用 java 邮件 api 将它们移动到特定文件夹,如下所示:

过滤器实现:

@Bean(name = ImapAdaptersUtil.DEFAULT_FILTER_BEAN_NAME)
@Scope(WebApplicationContext.SCOPE_APPLICATION)
public MessageSelector defaultFilter() {
    return message -> {
        if (message.getPayload() instanceof MimeMessage) {
            try {
                String from = Optional.ofNullable(((InternetAddress) ((MimeMessage) message.getPayload()).getFrom()[0]).getAddress()).orElse(GeneralConst.EMPTY_STRING);
                String subject = Optional.ofNullable(((MimeMessage) message.getPayload()).getSubject()).orElse(GeneralConst.EMPTY_STRING);

                if (!from.matches(DELIVERY_ERROR_FROM)
                        && !from.matches(SPAM_FROM)
                        && !subject.matches(DELIVERY_ERROR_SUBJECT)
                        && !subject.matches(OUT_OF_OFFICE)
                        && !subject.matches(SPAM_SUBJECT)) {
                    return true;
                }
            } catch (MessagingException me) {
                throw new ApplicationBusinessException(ApplicationBusinessException.ApplicationBusinessExceptionType.FUNCTIONAL_VIOLATION,
                        "Could not filter incoming email: " + me.getMessage());
            }
        }
        try {
            this.moveMessage(((MimeMessage) message.getPayload()));
        } catch (MessagingException me) {
            throw new ApplicationBusinessException(ApplicationBusinessException.ApplicationBusinessExceptionType.FUNCTIONAL_VIOLATION,
                    "Could not move incoming email: " + me.getMessage());
        }
        return false;
    };
}

移动到文件夹实施:

private void moveMessage(MimeMessage message) throws MessagingException {
    Folder folder = message.getFolder();
    Store store = folder.getStore();
    Folder[] folders = store.getDefaultFolder().list("*");
    for (Folder folder1 : folders) {
        LOGGER.info("folder name {}", folder1.getName());
    }

    Folder deliveryErrorFolder = store.getFolder("Delivery error");
    if (!deliveryErrorFolder.exists()) {
        if (deliveryErrorFolder.create(Folder.HOLDS_MESSAGES)) {
            deliveryErrorFolder.setSubscribed(true);
            move(message, folder, deliveryErrorFolder);
            LOGGER.info("Delivery error created");
        }
    } else {
        move(message, folder, deliveryErrorFolder);
    }
}

private void move(MimeMessage message, Folder folder, Folder spamFolder) throws MessagingException {
    List<javax.mail.Message> tempList = new ArrayList<>();
    tempList.add(message);
    javax.mail.Message[] tempMessageArray = tempList.toArray(new javax.mail.Message[0]);
    folder.copyMessages(tempMessageArray, spamFolder);
    LOGGER.info("message moved");
}

ImapMailReceiver 配置为集成流:

public static IntegrationFlow getImapAdapterIntegrationFlow(String imapsUrl, MessageSelector filter, QueueChannelSpec channelSpec) {
    return IntegrationFlows
            .from(Mail.imapInboundAdapter(imapsUrl)
                   
                            .userFlag("testSIUserFlag")
                            .simpleContent(false)
                            .autoCloseFolder(false)
                            .shouldMarkMessagesAsRead(true)
                            .javaMailProperties(getPropertiesBuilderConsumer()),
                    e -> e.autoStartup(true)
                            .poller(p -> p.fixedDelay(1000)))
            .filter(filter)
            .channel(channelSpec)
            .get();
}

我得到这个异常:

Caused by: java.lang.ClassCastException: class org.springframework.integration.mail.AbstractMailReceiver$IntegrationMimeMessage cannot be cast to class com.sun.mail.imap.IMAPMessage (org.springframework.integration.mail.AbstractMailReceiver$IntegrationMimeMessage and com.sun.mail.imap.IMAPMessage are in unnamed module of loader 'app')
at com.sun.mail.imap.Utility.toMessageSet(Utility.java:85)

是的...您要查找的内容从版本 5.4 开始可用:https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-inbound

Starting with version 5.4, it is possible now to return a MimeMessage as is without any conversion or eager content loading. This functionality is enabled with this combination of options: no headerMapper provided, the simpleContent property is false and the autoCloseFolder property is false.

所以,您的配置中的一切都很好 - 只有您需要将项目升级到最新的 Spring 集成。直接使用 5.4.5 或通过相应的最新 Spring Boot.