Send Mail using Java Mail, Thymeleaf and Spring Boot

Send Mail using Spring boot and Java Mail

In this snippet i used gmail smtp service but feel free to use your smtp of choice.

Prerequisites

Maven dependencies

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

Java Code

Create our mail entity

package com.yamicode.mail.model;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class Mail {
    @NotNull
    @Pattern(regexp = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
    private String email;
    @NotNull
    private String object;
    @NotNull
    private String message;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getObject() {
        return object;
    }

    public void setObject(String object) {
        this.object = object;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

The website used to get the email validation regex is: Email Regex

Create our rest controller to test our app.

package com.yamicode.mail.rest;

import com.yamicode.mail.model.Mail;
import com.yamicode.mail.service.MailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("api/send/mail")
@CrossOrigin("*")
public class MailRestController {

    @Autowired
    private MailService mailService;

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<?> sendMail(@Valid @RequestBody Mail mail, Errors errors){
        if(errors.hasErrors()){
            return new ResponseEntity<>(errors.getAllErrors(), HttpStatus.BAD_REQUEST);
        }
        return mailService.sendMail(mail);
    }

}

  • The @Valid annotation is the one handling our javax.validation.constraints defined in our entity. If an error exists the error will be binded to the errors variable.
package com.yamicode.mail.service;

import com.yamicode.mail.model.Mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.internet.MimeMessage;

@Service
public class MailService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MailService.class);

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private JavaMailSender javaMailSender;

    public ResponseEntity<?> sendMail(Mail mail){
        send(mail);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    public void send(Mail mail) {
    	//get and fill the template
        final Context context = new Context();
        context.setVariable("message", mail.getMessage());
        String body = templateEngine.process("email/email-template", context);
        //send the html template
        sendPreparedMail(mail.getEmail(), mail.getObject(), body, true);
    }

    private void sendPreparedMail(String to, String subject, String text, Boolean isHtml) {
        try {
            MimeMessage mail = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mail, true);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(text, isHtml);
            javaMailSender.send(mail);
        } catch (Exception e) {
            LOGGER.error("Problem with sending email to: {}, error message: {}", to, e.getMessage());
        }
    }

}

We used thymeleaf template engine to create our mail

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Yamicode Email</title>
</head>
<body>
    <table>
        <tbody>
            <tr>
                <td>Message: </td>
                <td><p th:text="|${message}|">Hello</p></td>
            </tr>
        </tbody>
    </table>
</body>
</html>

The mail configuration can be set in our application.yml

spring:
  mail:
    properties:
      mail:
        smtp:
          starttls:
            enable: true
          ssl:
            trust: smtp.gmail.com
          auth: true
    host: smtp.gmail.com
    username: your-email@gmail.com
    password: your-password
    port: 587

Source code:

The full implementation of this artcile can be found in the GitHub project. Download and unzip the source repository for this guide GIT, or clone it using Git: git clone https://github.com/YamiCode2016/send-mail-spring-boot.git