Spring Boot: Listening for incoming emails in your application
There are several options how to process incoming emails in our applications. We can for example route email into standard mailbox and periodically download emails into our application with POP3 protocol. Or we can run our own SMTP server inside Spring Boot application. And this is the case!
Adding Spring Boot project dependency
I prefer using Gradle for all my Spring Boot projects so adding dependency means adding one line into build.gradle file in my project directory. SubethaSMTP is library that contains embeddable SMTP server implementation, great option for our purpose.
compile ("org.subethamail:subethasmtp:3.1.7")
Starting SMTP server when Spring Boot starts
SMTP is an active service that must be started during Spring Boot application startup. To do so, we can create @Service
class, like the one below, with @PostConstruct
and @PreDestroy
annotated methods. We can also inject properties parameters that will help us to configure service properly. This code is detected during Spring Boot start up process and @PostConstruct
method is run for us. We must not to forget to stop SMTP server in @PreDestroy
method otherwise the service would occupy the TCP port.
@Service
public class SMTPServerService {
@Value("${smtpserver.enabled}")
String enabled="";
@Value("${smtpserver.hostName}")
String hostName="";
@Value("${smtpserver.port}")
String port="";
SMTPServer smtpServer;
public SMTPServerService() {
}
@PostConstruct
public void start() {
if(enabled.equalsIgnoreCase("true")){
SimpleMessageListenerImpl l = new SimpleMessageListenerImpl();
smtpServer = new SMTPServer(new SimpleMessageListenerAdapter(l));
smtpServer.setHostName(this.hostName);
smtpServer.setPort(Integer.valueOf(port));
smtpServer.start();
System.out.println("****** SMTP Server is running for domain "+smtpServer.getHostName()+" on port "+smtpServer.getPort());
} else {
System.out.println("****** SMTP Server NOT ENABLED by settings ");
}
}
@PreDestroy
public void stop() {
if(enabled.equalsIgnoreCase("true")){
System.out.println("****** Stopping SMTP Server for domain "+smtpServer.getHostName()+" on port "+smtpServer.getPort());
smtpServer.stop();
}
}
public boolean isRunning() {
return smtpServer.isRunning();
}
}
Processing incoming emails
While starting SMTP server with code above, we specified ‘SimpleMessageListenerImpl()
’ class as SMTP Server parameter. The processing class must implement ‘SimpleMessageListener
’ that requires implementation of two methods only. Method accept can check originator / recipient emails and optionally allow or reject email delivery. Method deliver then processes email based on application logic. Everything is quite clear and processing requires minimal of code.
public class SimpleMessageListenerImpl implements SimpleMessageListener {
public SimpleMessageListenerImpl() {
}
@Override
public boolean accept(String from, String recipient) {
return true;
}
@Override
public void deliver(String from, String recipient, InputStream data) {
Session session = Session.getDefaultInstance(new Properties());
MimeMessage m = new MimeMessage(session,data);
ReceivedEmail email=new ReceivedEmail(m);
// ... here we go with email message ...
}