How to send email using spring boot application

Hello i am going to walk you through the steps on how to implement an email sending feature in a springboot application. But, before we proceed i need to briefly explain what an email messaging is. Firstly an e-mail simply stands for electronic mail, its a service that runs in a program and communicates to a client through an internet protocol and a specific port. Usually these settings are gotten from the service providers and is used to configure your apllication to be able to send email messages.

In this article we are going to be sending our email using sendinblue.com just follow the link and create an account with them then choose email sending service once that is done you will be provided with the basic setup like the username, email password, port, host etc.

Head over to your springboot application which you have created using springinitializr.io then add these dependences to your pom.xml file

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Once this has been added you can refresh and start your application

Create a file to configure your application properties and set your properties as follows:

spring.mail.username=${email_username}
spring.mail.password=${email_password}
spring.mail.port=587
spring.mail.host=smtp-relay.sendinblue.com
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.required = true
spring.mail.properties.mail.smtp.starttls.enable= true
spring.mail.properties.mail.smtp.connectiontimeout= 5000
spring.mail.properties.mail.smtp.timeout = 5000
spring.mail.properties.mail.writetimeout = 5000
spring.mail.properties.mail.debug=true

Then head on to create a package called config inside your application/src/main/java/appName/config create your class as follows:

STEP 1: Create a class called mail with field variables called: "from", "to", "subject", "Html template"

import lombok.Builder;
import lombok.Data;

import java.util.Map;

@Data 
@Builder 
public class Mail;
private String from; 
private String to; 
private String subject; 
private HtmlTemplate htmlTemplate; 

@Data
public static class HtmlTemplate 
{ 
private String template; 
private Map<String, Object> props;


        public HtmlTemplate(String template, Map<String, Object> props) {
            this.template = template;
            this.props = props;
        }
    }
}

STEP 2: Create a sub class called Html Template and a constructor of the Html Templete which accepts two parameters "template" and a map object.

STEP 3: Create a class called EmailConfig annotate it with @Component and @Data this way springboot configures it as a bean and provides its Pojos where its needed. Or better still copy the codes below to your IDE. From the code snipet above you can see how we created the field variables and used it to refference our values from our application properties that we dont want to be made public. Then we created a method that will send the email called sendEmail which takes an object of mail as parameter. Ealier before now we had created a messaging Exception to enable us try and catch all possible messaging errors for more info on exception handling in java visit the link.

Spring provides a higher level of abstraction for sending electronic mail which shields the user from the specifics of underlying mailing system. We created a MimeMessage object which provides us with mailSender method to create a mimeMessage. also we created a MimeMessageHelper: It is the helper class for creating a MIME message. It offers support for inline elements such as images, typical mail attachments and HTML text content. We passed in the object of the mime message we created to the mime message helper this method also takes in root as "MULTIPART_MODE_MIXED_RELATED", and set the standard character set to "StandardCharsets.UTF_8.name()" we created a variable called "html" to store the content of our mail as seen in our code snippet. Our mime helper object provides us with the method to set its properties.

STEP 4: Once we had all that set up we then proceeded to creating a micro service for email sending in my case i called it email verification you can call it anything you want, i chose this approach just to separate my concerns. I created a service to send email to a user and another service to send to all users on the same platform

@Component 
@Data 
public class EmailConfig {

private final JavaMailSender mailSender;

@Autowired
private SpringTemplateEngine templateEngine;

@Value("${myApp.app.baseUrl}")
private String baseUrl;

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

@Value("${spring.mail.port}")
private short port;

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

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

@Value("${myApp.email.subject}")
private String subject;

@Value("${myApp.email.senderName}")
private String senderName;

public String getSenderName() {
    return senderName;
}

STEP 5: Copy the code below for method emailSending

@Async
public void sendEmail(Mail mail) throws MessagingException, IOException {
    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message,
            MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
            StandardCharsets.UTF_8.name());

STEP 6: create a html content variable

String html = getHtmlContent(mail);

STEP 7: Use the object of the mime message helper you created to set its properties.

helper.setTo(mail.getTo());
    helper.setFrom(mail.getFrom(), getSenderName());
    helper.setSubject(mail.getSubject());
    helper.setText(html, true);
    mailSender.send(message);
}

STEP 8: Create a helper method which accepts an object of mail to be sent

private String getHtmlContent(Mail mail) {

STEP 9: Create a context in this case java provides us with context class which has a method called "setVariables()" to set it properties. Once that is done we are returning a processed mail and its context using a template engine.

Context context = new Context();
context.setVariables(mail.getHtmlTemplate().getProps());
return templateEngine.process(mail.getHtmlTemplate().getTemplate(), context);
}
}

STEP 10: Now lets go over to our interface and create this two services

void sendEmailToASingleUser(String email, String subject, String message) throws MessagingException, IOException;
void sendEmailToAllUsers(String subject, String message) throws MessagingException, IOException;

STEP 11: Below is our service implementation in our implementation class

@Override
public void sendEmailToASingleUser(String email,String subject,
String message) throws MessagingException, IOException 
{

STEP 12: Check if the user with the email provided is present before sending the email.

if(userRepository.findUserByEmail(email).isPresent())
{
User newUser = userRepository.findUserByEmail(email).orElse(null);

STEP 13:Map out the object we want to send using the map object which allows us to store our object using keys and value.

Map<String, Object> properties = new HashMap<>();
properties.put("message", message);
properties.put("subject", subject);
assert newUser != null;
properties.put("name", newUser.getUsername());

STEP 14:Create an object of the mail and use stream builder to build our object we wish to send.

Mail mail = Mail.builder()
                .from(emailConfig.getUsername())
                .to(email)
                .htmlTemplate(new Mail.HtmlTemplate("message", properties))
                .subject(subject)
                .build();
        emailConfig.sendEmail(mail);
    }else {
        throw  new ResourceNotFound("Email address not found");
    }

}

STEP 15: This second code snippet bellow shows how i implemented send to all users.

@Override
public void sendEmailToAllUsers(String subject, String message) throws MessagingException, IOException {

STEP 16: Create a list of users

List<User> userList = userRepository.findAll();

STEP 17: Map the object we want to send

Map<String, Object > properties = new HashMap<>();

STEP 18: Because we have a list of users we need to loop through the list of users for every user send a mail to the user.

for (User aUser : userList) {
        Mail mail = Mail.builder()
                .from(emailConfig.getUsername())
                .to(user.getEmail())
                .htmlTemplate(new Mail.HtmlTemplate("message", properties))
                .subject(subject)
                .build();
        properties.put("subject", subject);
        properties.put("message", message);
        emailConfig.sendEmail(mail);
        log.info(" user --->{}", aUser);

    }

}

STEP 19: Create a helper method called sendMail which sends the mail

private void sendEmail(String email, String message) throws MessagingException, IOException {
    Map<String, Object> properties = new HashMap<>();
    properties.put("body", message);
    properties.put("email", email);

    Mail mail = Mail.builder()
            .from(emailConfig.getUsername())
            .to(email)
            .htmlTemplate(new Mail.HtmlTemplate("message", properties))
            .subject(emailConfig.getSubject())
            .build();
    emailConfig.sendEmail(mail);
}

Conclusion This allows me to send emails to a user or multiple users. It helped me grasp the core of Java mail sender and how to implement the class however this is just one of the ways you can integrate this service therr are other ways using xml configurations and a list of other email service providers to choose from. in my next article am going to be explaining how to implement SMS sending feature using springboot.