Практическое обучение Spring Boot (6): отправка электронных писем

Spring Boot

[TOC]

1. Введение

Отправка электронных писем должна быть одной из часто используемых функций.Будь то регистрация и активация пользователей, напоминания об истечении срока действия учетной записи или напоминания о бизнес-маркетинге, система должна автоматически отправлять электронные письма пользователям;

ТакSpring BootКак отправить письмо?

SpringвыпускJavaMailSenderУпростили процесс отправки почты, теперьSpring BootОн снова упакован.

То естьspring-boot-starter-mailэтот пакет зависимостей.

2. Зависимости установки

<!-- 邮件 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

3. Добавьте информацию о конфигурации

src/main/resources/application.yml

server:
  port: 9002

spring:
  mail:
    host: smtp.qq.com
    username: 149807666@qq.com
    password: sputxytreefvxrgoihef
  resources:
    static-locations: classpath:/resources/, classpath:/static/ ,classpath:/templates/

mail:
  fromMail:
    addr: alex@qq.com # 发邮件者

# 日志级别
logging:
  level:
    root: warn
    com.scaffold.test.mapper: trace
    com.scaffold.test.task: trace

мы здесь сQQ邮箱Например,smtp.qq.com 是邮箱服务器地址;

usernameЭто ваш адрес электронной почты,passwordваш пароль от электронной почты;

mai.fromMail.addrЭто адрес электронной почты отправителя.

4. Реализация кода

Entity --- Класс сущности почтовой информации: com.scaffold.test.entity.Mail

package com.scaffold.test.entity;

import lombok.Data;

@Data
public class Mail {

    // 发送给谁
    private String to;

    // 发送主题
    private String subject;

    // 发送内容
    private String content;

    // 附件地址
    private String filePath;
}

Сервис --- интерфейс почтового сервиса: com.scaffold.test.service.MailService

package com.scaffold.test.service;

import com.scaffold.test.entity.Mail;

public interface MailService {
    // 发送邮件
    public void sendMail(Mail mail);
}

ServiceImpl --- класс реализации интерфейса почтовой службы: com.scaffold.test.service.impl.MailServiceImpl

package com.scaffold.test.service.impl;

import com.scaffold.test.entity.Mail;
import com.scaffold.test.service.MailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.io.File;

@Service
public class MailServiceImpl implements MailService {

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

    @Autowired
    private JavaMailSender mailSender;

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

    // 只发送文本
    @Override
    public void sendMail(Mail mail) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(mailFrom);
        message.setTo(mail.getTo());
        message.setSubject(mail.getSubject());
        message.setText(mail.getContent());
        mailSender.send(message);
        logger.info("发送完毕");
    }

}

Контроллер --- Контроллер отправки почты: com.scaffold.test.controller.MailController

package com.scaffold.test.controller;

import com.scaffold.test.base.Result;
import com.scaffold.test.base.ResultGenerator;
import com.scaffold.test.entity.Mail;
import com.scaffold.test.service.MailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.MessagingException;

@RestController
@RequestMapping("/mail")
public class MailController {

    @Autowired
    private MailService mailService;

    // 发送不带格式的文本
    @Async
    @GetMapping("post")
    public Result postMail() {
        Mail mail = new Mail();
        mail.setTo("******@qq.com");
        mail.setSubject("automatic");
        mail.setContent("自动邮件发布");
        mailService.sendMail(mail);
        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }
}

Следует отметить, что код, который мы здесь используем,@AsyncАннотация, означающая, что это асинхронная операция, поэтому возвращаемыйResultОн тоже будет недействителен.Больше не буду комментировать неверный код.Когда я его писал,то он писался синхронно.

其实这里,用异步是对的,业务代码中,邮件发送不是业务关注的重点,可以延迟或者失败,所以没必要占用主进程;

Результат выглядит следующим образом:

Пока что простая функция отправки писем завершена.Если вы хотите публиковать автоматически, вам нужно добавить временные задачи.Вы можете обратиться к предыдущей статье:

Практическое обучение Spring Boot (5): задачи на определение времени

Здесь это повторяться не будет;

5. Расширение функций

5.1. Отправляйте электронные письма в формате HTML

Отправляя обычный текст, который иногда не соответствует нашим бизнес-требованиям, нам нужно отправлять электронные письма в формате HTML следующим образом:

существуетMailServiceдобавлено вsendHtmlMailМетод: com.scaffold.test.service.MailService

package com.scaffold.test.service;

import com.scaffold.test.entity.Mail;

import javax.mail.MessagingException;

public interface MailService {
    // 发送邮件
    public void sendMail(Mail mail);

    // 发送Html邮件
    public void sendHtmlMail(Mail mail) throws MessagingException;

}

Соответствующий метод реализации: com.scaffold.test.service.impl.MailServiceImpl

		// 发送Html邮件
    @Override
    public void sendHtmlMail(Mail mail) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            message.setFrom(mailFrom);
            helper.setTo(mail.getTo());
            helper.setSubject(mail.getSubject());
            helper.setText(mail.getContent(), true);

            mailSender.send(message);
            logger.info("发送Html邮件成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送Html邮件失败");
        }
    }

Вызов контроллера: com.scaffold.test.controller.MailController

		// 发送Html邮件
    @Async
    @GetMapping("postHtml")
    public Result postHtmlMail() throws MessagingException {
        String content = "<html>\n" +
                "<body>\n" +
                "<h3>hello! test Html test!</h3>\n" +
                "</body>\n" +
                "</html>";
        Mail mail = new Mail();
        mail.setTo("******@qq.com");
        mail.setSubject("Html格式邮件");
        mail.setContent(content);
        mailService.sendHtmlMail(mail);
        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

Результат выглядит следующим образом:

5.2. Отправляйте электронные письма с вложениями

Иногда нам нужно отправлять электронные письма с вложениями;

существуетMailServiceДобавьте метод sendAttachmentsMail в: com.scaffold.test.service.MailService.

package com.scaffold.test.service;

import com.scaffold.test.entity.Mail;

import javax.mail.MessagingException;

public interface MailService {
    // 发送邮件
    public void sendMail(Mail mail);

    // 发送Html邮件
    public void sendHtmlMail(Mail mail) throws MessagingException;

    // 发送带附件的邮件
    public void sendAttachmentsMail(Mail mail) throws MessagingException;
}

Соответствующий метод класса реализации: com.scaffold.test.service.impl.MailServiceImpl

    // 发送带附件的邮件
    @Override
    public void sendAttachmentsMail(Mail mail) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            message.setFrom(mailFrom);
            helper.setTo(mail.getTo());
            helper.setSubject(mail.getSubject());
            helper.setText(mail.getContent(), true);

            // 附件
            FileSystemResource resourse = new FileSystemResource(new File(mail.getFilePath()));
            // 添加附件
            helper.addAttachment("test.png", resourse);

            mailSender.send(message);
            logger.info("发送邮件成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送邮件失败");
        }
    }

Вызов контроллера: com.scaffold.test.controller.MailController

    // 发送带附件的邮件
    @Async
    @GetMapping("postAttachment")
    public Result postAttachmentsMail() throws MessagingException {
        Mail mail = new Mail();
        mail.setTo("***@qq.com");
        mail.setSubject("附件");
        mail.setContent("有附件,赶紧看下");
        mail.setFilePath("E:\\test.png");
        mailService.sendAttachmentsMail(mail);
        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

Эффект показан на рисунке:

5.3 Использованиеthymeleafшаблон отправить письмо

Так же для красоты формата иногда нужно使用模板发送邮件;

Здесь мы используемthymeleaf:

Установить зависимости

<!-- thymeleaf 模板 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
    <groupId>ognl</groupId>
    <artifactId>ognl</artifactId>
    <version>3.2.14</version>
</dpendency>

Вызов контроллера: com.scaffold.test.controller.MailController

 	@Autowired
    private SpringTemplateEngine templateEngine;

    // 发送 Html 模板邮件
    @Async
    @GetMapping("postTemplate")
    public void postTemplateMail() throws MessagingException {
        Context context = new Context();
        Map<String, Object> emailParam = new HashMap<>();
        emailParam.put("name", "产品终端更换名字");
        emailParam.put("content", "牛牛终端");
        emailParam.put("person", "Alex Wong");
        context.setVariable("emailParam", emailParam);
        String emailTemplate = templateEngine.process("emailTemplate", context);

        Mail mail = new Mail();
        mail.setTo("*****@qq.com");
        mail.setSubject("模板邮件");
        mail.setContent(emailTemplate);
        mailService.sendHtmlMail(mail);
    }

Файл шаблона:src/main/resources/templates/emailTemplate.html

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>mail</title>
</head>
<body>


<table align="center" cellpadding="0" cellspacing="0" width="600px">
    <tr>
        <td>
            <table align="center" border="0" cellpadding="0" cellspacing="0" width="600"
                   style="border-collapse: collapse;">
                <tr>
                    <td align="center" style="padding: 40px 0 30px 0;">
                        <img src='你的图片地址' style='width:183px height:47.50px'>
                    </td>
                </tr>

                <tr>
                    <td bgcolor="#ffffff" style="padding: 0px 30px 20px 30px">
                        <h3>产品名称变更通知</h3>

                        <table border="0" cellpadding="0" cellspacing="0" width="100%">
                            <tr>
                                <td colspan="2" style="padding: 0 0 3px 0">
                                    通知事项:<span th:text="${emailParam.name}"></span>
                                </td>
                            </tr>
                            <tr>
                                <td style="padding: 12px 0 3px 0">
                                    产品名称:<span th:text="${emailParam.content}"></span>
                                </td>
                            </tr>
                            <tr>
                                <td style="padding: 12px 0 3px">
                                    审批人:<span th:text="${emailParam.person}"></span>
                                </td>
                            </tr>

                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>

</table>
</body>
</html>

Эффект показан на рисунке:

6. Полный код

Entity --- Класс сущности почтовой информации: com.scaffold.test.entity.Mail

package com.scaffold.test.entity;

import lombok.Data;

@Data
public class Mail {

    // 发送给谁
    private String to;

    // 发送主题
    private String subject;

    // 发送内容
    private String content;

    // 附件地址
    private String filePath;
}

Сервис --- интерфейс почтового сервиса: com.scaffold.test.service.MailService

package com.scaffold.test.service;

import com.scaffold.test.entity.Mail;

import javax.mail.MessagingException;

public interface MailService {
    // 发送邮件
    public void sendMail(Mail mail);

    // 发送Html邮件
    public void sendHtmlMail(Mail mail) throws MessagingException;

    // 发送带附件的邮件
    public void sendAttachmentsMail(Mail mail) throws MessagingException;
}

ServiceImpl --- класс реализации интерфейса почтовой службы: com.scaffold.test.service.impl.MailServiceImpl

package com.scaffold.test.service.impl;

import com.scaffold.test.entity.Mail;
import com.scaffold.test.service.MailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.io.File;

@Service
public class MailServiceImpl implements MailService {

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

    @Autowired
    private JavaMailSender mailSender;

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

    // 只发送文本
    @Override
    public void sendMail(Mail mail) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(mailFrom);
        message.setTo(mail.getTo());
        message.setSubject(mail.getSubject());
        message.setText(mail.getContent());
        mailSender.send(message);
        logger.info("发送完毕");
    }

    // 发送Html邮件
    @Override
    public void sendHtmlMail(Mail mail) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            message.setFrom(mailFrom);
            helper.setTo(mail.getTo());
            helper.setSubject(mail.getSubject());
            helper.setText(mail.getContent(), true);

            mailSender.send(message);
            logger.info("发送Html邮件成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送Html邮件失败");
        }
    }

    // 发送带附件的邮件
    @Override
    public void sendAttachmentsMail(Mail mail) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            message.setFrom(mailFrom);
            helper.setTo(mail.getTo());
            helper.setSubject(mail.getSubject());
            helper.setText(mail.getContent(), true);

            // 附件
            FileSystemResource resourse = new FileSystemResource(new File(mail.getFilePath()));
            // 添加附件
            helper.addAttachment("test.png", resourse);

            mailSender.send(message);
            logger.info("发送邮件成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送邮件失败");
        }
    }
}

Контроллер --- Контроллер отправки почты: com.scaffold.test.controller.MailController

package com.scaffold.test.controller;

import com.scaffold.test.entity.Mail;
import com.scaffold.test.service.MailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.mail.MessagingException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/mail")
public class MailController {

    @Autowired
    private MailService mailService;

    @Autowired
    private SpringTemplateEngine templateEngine;

    // 发送不带格式的文本
    @Async
    @GetMapping("post")
    public void postMail() {
        Mail mail = new Mail();
        mail.setTo("**@qq.com");
        mail.setSubject("automatic");
        mail.setContent("自动邮件发布");
        mailService.sendMail(mail);
//        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

    // 发送Html邮件
    @Async
    @GetMapping("postHtml")
    public void postHtmlMail() throws MessagingException {
        String content = "<html>\n" +
                "<body>\n" +
                "<h3>hello! test Html test!</h3>\n" +
                "</body>\n" +
                "</html>";
        Mail mail = new Mail();
        mail.setTo("***@qq.com");
        mail.setSubject("Html格式邮件");
        mail.setContent(content);
        mailService.sendHtmlMail(mail);
//        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

    // 发送带附件的邮件
    @Async
    @GetMapping("postAttachment")
    public void postAttachmentsMail() throws MessagingException {
        Mail mail = new Mail();
        mail.setTo("****@qq.com");
        mail.setSubject("附件");
        mail.setContent("有附件,赶紧看下");
        mail.setFilePath("E:\\test.png");
        mailService.sendAttachmentsMail(mail);
//        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

    // 发送 Html 模板邮件
    @Async
    @GetMapping("postTemplate")
    public void postTemplateMail() throws MessagingException {
        Context context = new Context();
        Map<String, Object> emailParam = new HashMap<>();
        emailParam.put("name", "产品终端更换名字");
        emailParam.put("content", "牛牛终端");
        emailParam.put("person", "Alex Wong");
        context.setVariable("emailParam", emailParam);
        String emailTemplate = templateEngine.process("emailTemplate", context);

        Mail mail = new Mail();
        mail.setTo("***@qq.com");
        mail.setSubject("模板邮件");
        mail.setContent(emailTemplate);
        mailService.sendHtmlMail(mail);
//        return ResultGenerator.getSuccessResult().setMessage("发送成功");
    }

}