Sending Emails in Spring Boot using JavaMailSender API

Badjessa Roméo Bahoumda
4 min readOct 18, 2021

--

As Udeesa’s grows, it’s become apparent that was time to move from the Wix platform to a completely self managed infrastructure.

As with any systems that handle its own users, email becomes a vital aspect. You need to send confirmation emails, welcome emails, updates etc… Wix took care of a lot of these things for us, however a move away meant the responsibility shifted to us. Implementing such a system initially felt like a daunting task but it turns out not to be as complex thanks to the JavaMailSender api provided by the Spring boot framework.

Prerequisites

  • Spring Boot Project
  • Email client to use (in our case we gmail)
  • This article assumes that you have some understanding of Spring Boots configuration files as well as Beans.

Implementation

First, we need to import the library into our project. We used gradle for dependency management in our project

implementation 'org.springframework.boot:spring-boot-starter-mail:2.5.5'

Next, we need a Bean that would allow us to inject the instance of our MailSender into our Spring container.

Before doing that, we need to define some properties to appropriately configure our MailSender. This is especially true, if the email used depends on your environment (i.e send test emails in a test environment). Here we can leverage the application.properties file in our Spring project.

spring.profiles.active=dev## Email configuration
udeesa.email.sender.host=smtp.gmail.com
udeesa.email.sender.debug=true
udeesa.email.sender.user={youremail}
udeesa.email.sender.password={yourpassword}

Note: spring.profiles.active allows us to override these values based on different profiles (dev, test, prod, etc…)

Here we define a couple of things

  • udeesa.email.sender.host: defines the outgoing smtp server we want to use to send our emails, in our case we use gmail.
  • udeesa.email.sender.debug: set to true if we want to debug the MailSender (I chose to only debug in my dev environment, and turn it off in other environments)
  • udeesa.email.sender.user: the username or email of the account you will be sending the email from.
  • udeesa.email.sender.password: the password associated with the email defined above.

Now that we’ve defined some properties, it is time to create a configuration and instantiate a Bean providing an instance of JavaMailSender.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
@ConfigurationProperties
public class EmailConfig {

private static final int GMAIL_SMTP_PORT = 587;

@Value("${udeesa.email.sender.host}")
private String host;

@Value("${udeesa.email.sender.user}")
private String user;

@Value("${udeesa.email.sender.password}")
private String password;

@Value("${udeesa.email.sender.debug}")
private Boolean debug;

@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
// Set up Gmail config
mailSender.setHost(host);
mailSender.setPort(GMAIL_SMTP_PORT);

// Set up email config (using udeesa email)
mailSender.setUsername(user);
mailSender.setPassword(password);

Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", debug);
return mailSender;
}
}

Here we instantiate the JavaMailSender object and configure that object using the properties we defined in our properties file. We define additional properties to our mail sender. The properties may differ depending on the outgoing mail server you want to use, I chose to hardcode those properties explicitly since they are not environment dependent. Gmail has a list of the properties it needs here https://support.google.com/mail/answer/7104828?hl=en&rd=3&visit_id=637701140744469738-2270293891

Using JavaMailSender

Now that we have defined a bean providing the Mail Sender, we can now use it our EmailService

import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Component
@NoArgsConstructor
public class EmailService {
private final static String EMAIL_CONFIRMATION_SUBJECT = "Confirm your udeesa account";

@Autowired
private JavaMailSender javaMailSender;

public void sendConfirmationEmail(String token, String email) {
// build email
// send message
String message = "Welcome to Udeesa, test token" + token;
String from = "no-reply@udeesa.org";
send(email, from, message);
}

@Async
private void send(String to, String from, String email) {
try {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper =
new MimeMessageHelper(mimeMessage, "utf-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(EMAIL_CONFIRMATION_SUBJECT);
helper.setText(email);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
LOGGER.error("failed to send email", e);
throw new IllegalStateException("failed to send email");
}
}
}

We inject the instance of our Mail Sender in our EmailService using the Autowired annotation. In our send method, we create a MimeMessage; set the appropriate to and from values. We set the subject and the text we want in our message and send the email.

Configure you email (if you use gmail)

Gmail often rejects apps that do not meet the security standards. Fortunately, Google gives you the option to allow less secure apps which worked quite well for us. In order to do you need to log into the account you will be using to send emails and go to https://myaccount.google.com/lesssecureapps and turn on Allow less secure apps

That’s it you should now be able to send emails from our Spring project.

Thanks for reading this article, This is my first technical blog post so Feedback is always welcomed!

Check out how we are revolutionizing our education system using XR technologies at Udeesa

--

--

Badjessa Roméo Bahoumda

Software Engineer, CTO of Udeesa Systemic & Technology. My interest lies in Software Engineering, XR technologies and applications and Game Development