简体   繁体   中英

spring-integration-mail Receiver mail for read email program in spring boot

I copied code from git for read emails I tired many but facing same as below errors in console while running the application. Please help me resolve this:

enter image description here

This is my Application.yaml: Here my specified username and password are correct only

logging:
  level:
    root: INFO
    org.ygaros: DEBUG

spring:
  mail:
    username: arunofficial302@gmail.com
    password: ***************
    properties:
      protocol: imaps
      host: imap.gmail.com
      port: 993

This is my config file:

package com.htc.mailOperation.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.mail.ImapMailReceiver;
import org.springframework.integration.mail.MailReceiver;
import org.springframework.integration.mail.MailReceivingMessageSource;
import org.springframework.messaging.Message;

import com.htc.mailOperation.service.MailReceiverService;

import javax.mail.internet.MimeMessage;

@Configuration
@EnableIntegration
public class MailConfig {

    private static final Logger log = LoggerFactory.getLogger(MailConfig.class);
    
    @Autowired
    private MailReceiverService receiverService;

    @Value("${spring.mail.username}")
    private String USERNAME;

    @Value("${spring.mail.password}")
    private String PASSWORD;

    @Value("${spring.mail.properties.port}")
    private int IMAP_PORT;

    @Value("${spring.mail.properties.protocol}")
    private String IMAP_PROTOCOL;

    @Value("${spring.mail.properties.host}")
    private String IMAP_HOST;

    /*
        Define a channel where we send and get the messages (mails in this example).
        MessageSource is sending messages to this channel.
        DirectChannel is a SubscribableChannel.
     */
    @Bean("incomingEmailsChannel")
    public DirectChannel defaultChannel() {
        DirectChannel directChannel = new DirectChannel();
        directChannel.setDatatypes(MimeMessage.class);
        return directChannel;
    }
    @Bean
    public MailReceiver imapMailReceiver() {
        String url = String.format(
                "%s://%s:%s@%s:%s/INBOX", IMAP_PROTOCOL, USERNAME, PASSWORD, IMAP_HOST, IMAP_PORT
        );
        log.debug("IMAP url: {}", url.replace(PASSWORD, "x".repeat(8)));

        ImapMailReceiver imapMailReceiver = new ImapMailReceiver(url);
        imapMailReceiver.setShouldMarkMessagesAsRead(true);
        imapMailReceiver.setShouldDeleteMessages(false);
        /*
            Attach content to message because by default the MimeMessage
            doesn't contain content body.
         */
        imapMailReceiver.setSimpleContent(true);
        //imapMailReceiver.setMaxFetchSize(1);

        return imapMailReceiver;
    }

    /*
      Provide MessageSource of Mails as spring integration Messages from ImapMailReceiver to be sent
      through incomingEmailsChannel.
      Poller with defined rate at which the messages are pushed to the channel
      (if there are any) every 5 sec.
   */
    @Bean
    @InboundChannelAdapter(
            channel = "incomingEmailsChannel",
            poller = @Poller(fixedDelay = "5000")

    )
    public MailReceivingMessageSource mailMessageSource(MailReceiver mailReceiver) {
        return new MailReceivingMessageSource(mailReceiver);

    }

    /*
        Connect (subscribe) to incomingEmailsChannel channel and provide method to
        handle each individual messages.
     */
    @ServiceActivator(inputChannel = "incomingEmailsChannel")
    public void receive(Message<MimeMessage> message) {
        receiverService.handleReceivedMail(message.getPayload());
    }
}

This is my service file:

package com.htc.mailOperation.service;

import org.apache.commons.mail.util.MimeMessageParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;

import javax.activation.DataSource;
import javax.mail.internet.MimeMessage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

@Service
public class MailReceiverService {

    private static final Logger log = LoggerFactory.getLogger(MailReceiverService.class);
    private static final String ATTACHMENTS_FOLDER_STORE = "data";

    public void handleReceivedMail(MimeMessage receivedMessage){
        try {
            MimeMessageParser mimeMessageParser = new MimeMessageParser(receivedMessage);
            mimeMessageParser.parse();

            logMail(mimeMessageParser);
            saveAttachments(mimeMessageParser);

            /*
                To delete downloaded email
                Setting those flag will delete messages only when we use folder.close(true);
            message.setFlag(Flags.Flag.DELETED, true);
             */
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private void logMail(MimeMessageParser mimeMessageParser) throws Exception {
        log.debug("From: {} To: {} Subject: {}",
                mimeMessageParser.getFrom(), mimeMessageParser.getTo(), mimeMessageParser.getSubject());
        log.debug("Mail content: {}", mimeMessageParser.getPlainContent());

    }

    private void saveAttachments(MimeMessageParser parser){
        List<DataSource> attachments = parser.getAttachmentList();
        log.debug("Email has {} attachment files", attachments.size());
        attachments.forEach(dataSource -> {
            String fileName = dataSource.getName();
            if(fileName != null && fileName.length() > 0){
                String rootDirPath = new FileSystemResource("").getFile().getAbsolutePath();

                createDirectoryIfNotExists(rootDirPath);

                String attachmentFilePath = rootDirPath +
                        File.separator +
                        ATTACHMENTS_FOLDER_STORE +
                        File.separator +
                        fileName;
                File attachmentFile = new File(attachmentFilePath);

                log.info("Attachment file saved to: {}", attachmentFilePath);

                try(
                        InputStream in = dataSource.getInputStream();
                        OutputStream out = new FileOutputStream(attachmentFile)
                        ){
                    copyStream(in, out);
                }catch(IOException e){
                    log.error("Failed to save file.", e);
                }
            }
        });
    }

    private void createDirectoryIfNotExists(String directoryPath) {
        Path of = Path.of(directoryPath);
        if (!Files.exists(of)) {
            try {
                Files.createDirectories(of);
            } catch (IOException e) {
                log.error("An error: {} on creating: {}", e, directoryPath);
            }
        }
    }

    private void copyStream(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[8192]; //just my standard base buffer
        int readByteCount;
        while(-1 != (readByteCount = in.read(buffer))){
            out.write(buffer, 0, readByteCount);
        }
    }
}

can someone please help me with this?

You need to convert your username and password to x-www-form-urlencoded format before build url. For example:

...
public MailReceiver imapMailReceiver() {
   USERNAME = URLEncoder.encode(USERNAME, StandardCharsets.UTF_8.name());
   PASSWORD = URLEncoder.encode(PASSWORD, StandardCharsets.UTF_8.name());
   String url = String.format(
                "%s://%s:%s@%s:%s/INBOX", IMAP_PROTOCOL, USERNAME, PASSWORD, IMAP_HOST, IMAP_PORT
        );
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM