Reputation: 1
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:
This is my Application.yaml : Here my specified username and password are correct only
logging:
level:
root: INFO
org.ygaros: DEBUG
spring:
mail:
username: [email protected]
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?
Upvotes: 0
Views: 1496
Reputation: 11
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
);
...
Upvotes: 1