Writing in the front

As we all know, if there is an alert or monitoring need, we can send a text message or email to notify the system. In this article, I intend to explain the Email service of SpringBoot. We all know that email is supposed to be one of the must-have features on a website, whether it’s sign-up verification, forgetting passwords or sending marketing messages to users. We used to use JavaMail apis to write code for sending emails, but then Spring introduced JavaMailSender to simplify the process of sending emails. SpringBoot then encapsulates this and now spring-boot-starter-mail. If you’ve read my previous article, you know that SpringBoot encapsulates most of the requirements as scenario initiators. Mail is the scene initiator.

Learn about Mail services

The most common mail-related protocols are SMTP, IMAP, and POP3, so let’s look at these three protocols first.

SMTP is the Simple Mail Transfer Protocol (SMTP). It is a set of specifications for transferring mails from source addresses to destination addresses to control the Transfer mode of mails. SMTP authentication requires users to provide an account and password to log in to the server, which is designed to prevent users from being invaded by spam.

The Internet Message Access Protocol (IMAP) allows users to obtain and download mail information from mail servers. IMAP, like POP, is a mail retrieval protocol.

POP3 is short for Post Office Protocol 3 (Post Office Protocol 3). POP3 allows clients to remotely manage emails on servers. POP3 is often used for “offline” mail processing, which allows clients to download server messages and then the messages on the server will be deleted. At present, many POP3 mail servers only provide the function of downloading mail, the server itself does not delete mail, this is an improved version of the POP3 protocol.

So what’s the difference between IMAP and POP3? The biggest difference between the two is that IMAP allows bidirectional communication. That is, operations performed on the client side are reported back to the server. For example, operations such as receiving emails or marking read on the client side are synchronized by the server. Although POP protocol also allows the client to download server mail, but the operations on the client side will not be synchronized to the server above, such as receiving or marking read mail on the client side, the server will not synchronize these operations.

SpringBoot related classes

The two utility classes in SpringBoot for mail services are JavaMailSender and JavaMailSenderImpl. They are the interface and implementation classes provided by Spring to integrate mail services. They are known for their simple and efficient design. It is currently the mainstream tool for sending mail and integrating mail services in the Java backend. So how do you send mail through JavaMailSenderImpl? Very simply, inject JavaMailSenderImpl directly into the business class and call the Send method to send the mail. Simple messages can be sent with SimpleMailMessage, while complex messages (such as adding attachments) can be sent with MimeMessage built with MimeMessageHelper.

SpringBoot works out of the box for email services based on official built-in auto-configuration, Read the source code can know mail automatically configure class (MailSenderPropertiesConfiguration) provides a mail service instance context (JavaMailSenderImpl).

Specific tutorial

configuration

First we create a new project that contains only the most basic Web scenario, and then we introduce the following dependencies in POM.xml:

<dependencies>
    <dependency> 
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency> 
</dependencies>
Copy the code

Next, we configure mail in the application.properties main configuration file. The configuration content is as follows, and I have made relevant comments

spring.mail.host=smtp.163.com
spring.mail.username=amazing
spring.mail.password=xxxxxx  # This is not the account password, it is the third party login verification code
spring.mail.default-encoding=UTF-8
[email protected]
Copy the code

The address of the email server above, I here let out the common limited mail server address

QQ Mailbox (mail.qq.com) POP3 Server ADDRESS: pop.qq.com (port: 110) SMTP server address: smtp.qq.com (port: 25) The SMTP server requires authentication. Netease E-mail: POP3 Server ADDRESS :pop.163.com (port: 110) SMTP server address :smtp.163.com (port: 25) Google.com: POP3 server address :pop.gmail.com (SSL enabled port: 995) SMTP server ADDRESS :smtp.gmail.com (SSL enabled port: 587) Aliyun mailbox (mail.aliyun.com) : POP3 Server address :pop3.aliyun.com (SSL encrypted port: 995; Unencrypted port: 110) SMTP server address :smtp.aliyun.com (SSL encrypted port: 465; Unencrypted port: 25) IMAP server address: imap.aliyun.com (SSL encrypted port: 993; Unencrypted port: 143) Sina Email (sina.com) : POP3 Server Address :pop3.sina.com.cn (port: 110) SMTP server address :smtp.sina.com.cn (port: 25)Copy the code

Simple to use

This completes the basic configuration for SpringBoot to use the mail Service, so let’s use it briefly. First we write the Service, directory structure is as follows

public interface MailService {
    public void sendSimpleMail(String to, String subject, String content);
}
Copy the code
@Component
public class MailServiceImpl implements MailService{

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JavaMailSender mailSender;

    @Value("${mail.fromMail.addr}")
    private String from;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);

        try {
            mailSender.send(message);
            logger.info("Simple mail has been sent.");
        } catch (Exception e) {
            logger.error("An exception occurred while sending simple mail!", e); }}}Copy the code

Write the Test class to test, and a simple text delivery is done.

Enrich your email

However, in normal use, we usually add pictures or attachments to the email to enrich the content of the email. Here is how to use Spring Boot to send rich emails.

Send an HTML email

All else unchanged add the sendHtmlMail method to MailService

public void sendHtmlMail(String to, String subject, String content) {
    MimeMessage message = mailSender.createMimeMessage();

    try {
        //true indicates that a multipart message needs to be created
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        mailSender.send(message);
        logger.info("HTML email sent successfully");
    } catch (MessagingException e) {
        logger.error("Exception occurred while sending HTML mail!", e); }}Copy the code

Build HTML content in the test class, test send

@Test
public void testHtmlMail(a) throws Exception {
    String content="<html>\n" +
            "<body>\n" +
            " 

hello world ! This is an Html email!

\n"
+ "</body>\n" + "</html>"; MailService.sendHtmlMail("
[email protected]"."test simple mail",content); } Copy the code

Send a message with attachments

As usual, add the sendAttachmentsMail method to MailService.

public void sendAttachmentsMail(String to, String subject, String content, String filePath){
    MimeMessage message = mailSender.createMimeMessage();

    try {
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        FileSystemResource file = new FileSystemResource(new File(filePath));
        String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
        helper.addAttachment(fileName, file);

        mailSender.send(message);
        logger.info("Attached mail has been sent.");
    } catch (MessagingException e) {
        logger.error("An exception occurred while sending message with attachment!", e); }}Copy the code

Adding multiple attachments can use multiple helper.addattglide (fileName, file), and then add test methods in your test class

@Test
public void sendAttachmentsMail(a) {
    String filePath="e:\\tmp\\application.log";
    mailService.sendAttachmentsMail("[email protected]"."Subject: Mail with Attachments"."Attached please check!", filePath);
}
Copy the code

Send messages with static resources

Static resources in mail generally refer to images. Add sendAttachmentsMail to MailService.

public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
    MimeMessage message = mailSender.createMimeMessage();

    try {
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        FileSystemResource res = new FileSystemResource(new File(rscPath));
        helper.addInline(rscId, res);

        mailSender.send(message);
        logger.info("Message embedded with static resource has been sent.");
    } catch (MessagingException e) {
        logger.error("An exception occurred while sending a message embedded with a static resource!", e); }}Copy the code

Add test methods to the test class

@Test
public void sendInlineResourceMail(a) {
    String rscId = "neo006";
    String content= This is the mail with pictures:  + rscId + "\' ></body></html>";
    String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png";

    mailService.sendInlineResourceMail("[email protected]"."Subject: This is an email with a picture", content, imgPath, rscId);
}
Copy the code

Adding multiple images can be done using multiple and helper.addinline (rscId, res)

Mail system

This is the basic service for sending mail, but if we want to make a mail system, we need to consider the following issues, the first is the mail template, we will receive emails like this all the time



Only the user name neo is changing, and the contents of other emails remain the same. It would not be elegant if manual stitching was required every time an email was sent, and it would be inconvenient if the code needed to be changed every time the template was modified. Therefore, it is recommended to make an email template to deal with the needs of such emails. The essence of the template is very simple, is in the template to replace the changed parameters, convert to HTML string, here to the example of thymeleaf, the first step of course is to import thymeleaf package.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Copy the code

Then create emailtemplate.html in Resorces/Templates

<! DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/> <title> title </title> </head> <body> <br/> <a href="#" th:href="@{ http://www.xxx.com/neo/{id}(id=${id}) }"> Activate account </a> </body> </ HTML >Copy the code
@Test
public void sendTemplateMail(a) {
    // Create the message body
    Context context = new Context();
    context.setVariable("id"."006");
    String emailContent = templateEngine.process("emailTemplate", context);

    mailService.sendHtmlMail("[email protected]"."Subject: This is a template email",emailContent);
}
Copy the code

Of course, it should be emphasized that when we implement the mailbox service, there will always be mail delivery failure due to various reasons, such as too frequent mail delivery and network abnormalities. In this case, we generally consider sending the email again, which can be divided into the following steps to achieve:

  • When receiving a send mail request, the request is first logged and stored.
  • Call the mail sending interface to send the mail and record the sending result in the database.
  • During the periodic system scanning period, if the mail fails to be sent and the mail attempts are less than three times, the mail can be sent again

The last

Most of the time, mail delivery is not an outcome that our main business must care about, such as notification class, notification class business can allow delay or failure. At this time, asynchronous mail can be sent to speed up the execution of the main transaction. In the actual project, MQ mail sending parameters can be used to monitor the message queue and start sending mail.