Java Mail Framework using Spring Boot – Step by Step Guide With Source Code
Every application be it desktop or web, needs to send some kind of notification via mail. The scenarios may differ as per requirements like registration mail, order confirmation or any batch job completion.
Java Mail Framework using Spring Boot
In this article, we will see a simple but powerful Java Mail sending framework using Spring Boot.
Software used for this example
- Java 1.8
- Spring Boot 1.5.2.RELEASE
- FakeSMTP
- Eclipse
As mentioned above we will be using Spring Boot Mail to provide all the boilerplate code and configuration. Below is the pom file entry for mail
1 2 3 4 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> |
We will simply build the simple template system on top of that. This Java Mail Framework will be able to send HTML as well as Plain text emails. You can download source code from here.
As a basic requirement for any mail, we need few details like to, from, subject, message. To hold this information we will define a simple java bean as below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public class Email { private String from; private List<String> to; private List<String> cc; private String subject; private String message; private boolean isHtml; public Email() { this.to = new ArrayList<String>(); this.cc = new ArrayList<String>(); } public Email(String from, String toList, String subject, String message) { this(); this.from = from; this.subject = subject; this.message = message; this.to.addAll(Arrays.asList(splitByComma(toList))); } public Email(String from, String toList, String ccList, String subject, String message) { this(); this.from = from; this.subject = subject; this.message = message; this.to.addAll(Arrays.asList(splitByComma(toList))); this.cc.addAll(Arrays.asList(splitByComma(ccList))); } //getters and setters not mentioned for brevity private String[] splitByComma(String toMultiple) { String[] toSplit = toMultiple.split(","); return toSplit; } public String getToAsList() { return AppUtil.concatenate(this.to, ","); } } |
You can see that we have added some convenience constructors. After this, we will define a template class which will help us to load the required HTML or text template and prepare the message body out of it. This class will also provide dynamic variable replacement in the message body.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class EmailTemplate { private String templateId; private String template; private Map<String, String> replacementParams; public EmailTemplate(String templateId) { this.templateId = templateId; try { this.template = loadTemplate(templateId); } catch (Exception e) { this.template = Constants.BLANK; } } private String loadTemplate(String templateId) throws Exception { ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("email-templates/" + templateId).getFile()); String content = Constants.BLANK; try { content = new String(Files.readAllBytes(file.toPath())); } catch (IOException e) { throw new Exception("Could not read template with ID = " + templateId); } return content; } public String getTemplate(Map<String, String> replacements) { String cTemplate = this.getTemplate(); if (!AppUtil.isObjectEmpty(cTemplate)) { for (Map.Entry<String, String> entry : replacements.entrySet()) { cTemplate = cTemplate.replace("{{" + entry.getKey() + "}}", entry.getValue()); } } return cTemplate; } //getters and setters } |
You can see that the class accepts and template ID which it tries to load from /resources/email-templates folder. Here is the project structure.
Also, you can see the utility method which gives us the message body after replacing each variable form template that is wrapped in {{var_name}} with the appropriate value from the Map you have passed to it.
Now let’s check the SMTP configuration part. As we are using Spring Boot, we don’t have to do anything except specifying the correct server details in application properties and use the JavaMailSender in your application. We have below details in our file
1 2 3 4 |
spring.mail.host=localhost spring.mail.port=25 spring.mail.protocol=smtp spring.mail.defaultEncoding=UTF-8 |
If you are wondering how SMTP is working on the localhost then its magic of FakeSMTP. It provides a simple runnable jar that works as our local SMPT server and we can test mails from our dev system. Once you download and run the jar on your machine it will look like this.
Here is our Email Service which provides utility methods to send HTML or PLAIN TEXT mails.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
@Component public class EmailService { @Autowired private JavaMailSender mailSender; private static final ApplicationLogger logger = ApplicationLogger.getInstance(); public void send(Email eParams) { if (eParams.isHtml()) { try { sendHtmlMail(eParams); } catch (MessagingException e) { logger.error("Could not send email to : {} Error = {}", eParams.getToAsList(), e.getMessage()); } } else { sendPlainTextMail(eParams); } } private void sendHtmlMail(Email eParams) throws MessagingException { boolean isHtml = true; MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message); helper.setTo(eParams.getTo().toArray(new String[eParams.getTo().size()])); helper.setReplyTo(eParams.getFrom()); helper.setFrom(eParams.getFrom()); helper.setSubject(eParams.getSubject()); helper.setText(eParams.getMessage(), isHtml); if (eParams.getCc().size() > 0) { helper.setCc(eParams.getCc().toArray(new String[eParams.getCc().size()])); } mailSender.send(message); } private void sendPlainTextMail(Email eParams) { SimpleMailMessage mailMessage = new SimpleMailMessage(); eParams.getTo().toArray(new String[eParams.getTo().size()]); mailMessage.setTo(eParams.getTo().toArray(new String[eParams.getTo().size()])); mailMessage.setReplyTo(eParams.getFrom()); mailMessage.setFrom(eParams.getFrom()); mailMessage.setSubject(eParams.getSubject()); mailMessage.setText(eParams.getMessage()); if (eParams.getCc().size() > 0) { mailMessage.setCc(eParams.getCc().toArray(new String[eParams.getCc().size()])); } mailSender.send(mailMessage); } } |
Below is the code to send mail using our template system.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Autowired EmailService emailService; String from = "pavan@localhost"; String to = "solapure@localhost"; String subject = "Java Mail with Spring Boot"; EmailTemplate template = new EmailTemplate("hello-world.html"); Map<String, String> replacements = new HashMap<String, String>(); replacements.put("user", "Pavan"); replacements.put("today", String.valueOf(new Date())); String message = template.getTemplate(replacements); Email email = new Email(from, to, subject, message); email.setHtml(true); emailService.send(email); |
and here is our template, you can see how we have used the replacement variables and replaced them dynamically while sending mail. Plain text templates will be similarly prepared and processed.
Once you run the application you will see an email entry immediately in your FakeSMTP server as
You can double click the mail and see how it looks. Check below Tadaaa!!!!! It’s your HTML mail
Isn’t it easy? Go ahead and download the code from our Github and use it.
Please get back to me if you see any issue in the code or need the help of some sort.
Hello,
I thank you for this good tutorial. After following the steps, when I send an email I receive the email but with an empty body.
Cordially.
Hi Yague,
Can you try and debug if email message is being set during the process?
how to add multiple Recipient in To field and how to add cc too
could you please provide the code for mail reader???
Hi Madhuleena,
Are you referring to the mail screens from the article? If yes, then for that I am using FakeSMTP third-party open source application
where is the attachment code for attaching one file.
The example shared do not have any reference code for attachment. I am yet to work on that. If I manage to develop it soon, I will share.
Thanks!
Please provide the ‘AppUtil’ class
It gives an error to the AppUtil
please provide the solution
Hi Meghana,
Did you pull the latest code from GIT? If not please try with the latest code – https://github.com/pavansolapure/opencodez-samples/tree/master/mail-demo
Hi Pavan,
It’s nice example.
How about if We want to use google, yahoo or company email?
Is there anything else we have to config?
Do You have any example for that?
Thank You very much.
Hi Hendi,
If you need to use Google or any custom SMTP then you need to have access to the SMTP server.
You have to set user and password for SMTP services in the properties file. Change the host as per your need and set properties spring.mail.username, spring.mail.password
Thanks
Please provide the ‘AppUtil’ class!
Hi Alex
You can find that in our github repo – https://github.com/pavansolapure/opencodez-samples/blob/master/mail-demo/src/main/java/com/opencodez/util/AppUtil.java
for complete mail demo project refer – https://github.com/pavansolapure/opencodez-samples/tree/master/mail-demo
hi i searched lot in web we find only the send mail example using spring boot starter mail.if you please provide me the mail reader and the listen for new mail example using spring boot that will be more help full for me. thanks in advance