SpringBoot-Mail发送邮件

添加 maven 依赖

在 pom.xml 中添加 mail 和 thymeleaf 对应的依赖

<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>

邮件服务器属性配置

spring:
  mail:
    host: smtp.163.com
    username: username
    password: password
    protocol: smtp
    properties:
      mail:
        smtp:
          starttls:
            required: true
            enable: true
          auth: true

本文使用的是 163 邮箱,若使用其他邮箱,修改对应配置即可

测试发送邮件

发送文本邮件

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogServiceApplicationTests {


    @Autowired
    private JavaMailSender mailSender;


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


    @Test
    public void sendSimpleEmail() {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(sender);
        simpleMailMessage.setTo(sender);
        simpleMailMessage.setSubject("测试主题");
        simpleMailMessage.setText("测试内容");
        mailSender.send(simpleMailMessage);
    }

}

测试给自己发送一个文本邮件

发送 Html 邮件

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogServiceApplicationTests {


    @Autowired
    private JavaMailSender mailSender;


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


    @Test
    public void sendHtmlEmail() throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(message);
        messageHelper.setFrom(sender);
        messageHelper.setTo(sender);
        messageHelper.setSubject("测试主题");
        messageHelper.setText("<h1 style='color:red;'>测试内容</h1>", true);
        mailSender.send(message);
    }

}

发送附件邮件

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogServiceApplicationTests {


    @Autowired
    private JavaMailSender mailSender;


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


    @Test
    public void sendAttachmentsEmail() throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(message);
        messageHelper.setFrom(sender);
        messageHelper.setTo(sender);
        messageHelper.setSubject("测试主题");
        messageHelper.setText("测试附件");
        messageHelper.addAttachment("image.png", new ClassPathResource("/images/image.png"));
        mailSender.send(message);
    }

}

发送模板邮件

这个是 thymeleaf 的 html 模板,resource/template/mail-template.html

<table border="1">
    <tr>
        <th>Month</th>
        <th>Savings</th>
    </tr>
    <tr th:each="item:${data}">
        <td th:text="${item.name}">January</td>
        <td th:text="${item.value}">$100</td>
    </tr>
</table>
@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogServiceApplicationTests {


    @Autowired
    private JavaMailSender mailSender;


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


    @Autowired
    TemplateEngine templateEngine;


    @Test
    public void sendTemplateEmail() throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(message);
        messageHelper.setFrom(sender);
        messageHelper.setTo(sender);
        messageHelper.setSubject("测试主题");
        Context context = new Context();
        context.setVariables(new HashMap<String, Object>() {
            {
                put("data", Arrays.asList(
                        create("January", "$105"),
                        create("February", "$80"),
                        create("Irena", "$120"),
                        create("Saint", "$74"),
                        create("Enos", "$151"),
                        create("Kevan", "$25"),
                        create("Suzy", "$130"),
                        create("Trish", "$111"),
                        create("Rainy", "$51"),
                        create("Rance", "$77"),
                        create("Rowena", "$84")
                ));
            }
        });
        messageHelper.setText(templateEngine.process("mail-template", context), true);
        mailSender.send(message);
    }

}

我没在 spring 中配置了视图解析器来解析 thymeleaf 模板,返回视图。
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

完整的 MailUtil

@Slf4j
public class MailUtil {

    private static JavaMailSender mailSender;

    /**
     * 发送方 默认获取 spring.mail.username
     */
    private static String sender;

    private static TemplateEngine templateEngine;

    private static String getSender() {
        if (StringUtils.isEmpty(sender)) {
            sender = SpringContextUtil.getProperty("spring.mail.username");
        }
        return sender;
    }

    private static JavaMailSender getMailSender() {
        if (mailSender == null) {
            mailSender = SpringContextUtil.getBean(JavaMailSender.class);
        }
        return mailSender;
    }

    private static TemplateEngine getTemplateEngine() {
        if (templateEngine == null) {
            templateEngine = SpringContextUtil.getBean(TemplateEngine.class);
        }
        return templateEngine;
    }


    public static MailHelper create() {
        return new MailHelper(getSender(), null);
    }

    public static MailHelper create(String subject, String... receivers) {
        return new MailHelper(getSender(), subject, receivers);
    }

    public static MailHelper create(String sender, String subject, String... receivers) {
        return new MailHelper(sender, subject, receivers);
    }


    public static class MailHelper {

        private String sender;

        /**
         * 接收方列表,set 是为了去重
         */
        private Collection<String> receivers = new HashSet<>();

        /**
         * 抄送人列表,set 是为了去重
         */
        private Collection<String> ccs = new HashSet<>();

        /**
         * 邮件主题
         */
        private String subject;

        /**
         * 邮件内容
         */
        private String content;

        /**
         * 是否为 html
         */
        private boolean html;

        /**
         * 附件
         */
        private Map<String, InputStreamSource> attachments = new HashMap<>();

        /**
         * 内联资源
         */
        private Map<String, Resource> inlines = new HashMap<>();


        MailHelper(String sender, String subject, String... receivers) {
            this.sender = sender;
            this.receivers.addAll(Arrays.asList(receivers));
            this.subject = subject;
        }


        public MailHelper receiver(String... receivers) {
            this.receivers.addAll(Arrays.asList(receivers));
            return this;
        }

        /**
         * 设置主题
         */
        public MailHelper subject(String subject) {
            this.subject = subject;
            this.html = false;
            return this;
        }

        /**
         * 创建文本邮件
         *
         * @param content 内容
         */
        public MailSender text(String content) {
            this.content = content;
            this.html = false;
            return createMailSender();
        }

        /**
         * 创建 html 邮件
         *
         * @param content html
         */
        public MailSender html(String content) {
            this.content = content;
            this.html = true;
            return createMailSender();
        }

        /**
         * 创建模板邮件
         *
         * @param template  模板名称
         * @param variables 模板变量
         */
        public MailSender template(String template, Map<String, Object> variables) {
            Context context = new Context();
            context.setVariables(variables);
            this.content = getTemplateEngine().process(template, context);
            this.html = true;
            return createMailSender();
        }


        /**
         * 创建 MailSender
         */
        private MailSender createMailSender() {
            // 对参数进行校验
            Assert.hasLength(sender, "sender 不能为空");
            Assert.notEmpty(receivers, "receiver 不能为空");
            Assert.hasLength(subject, "subject 不能为空");
            Assert.hasLength(content, "content 不能为空");
            return new MailSender(this);
        }


        /**
         * 添加抄送人
         *
         * @param ccs 抄送人
         */
        public MailHelper addCc(String... ccs) {
            return addCc(Arrays.asList(ccs));
        }

        /**
         * 添加抄送人
         *
         * @param ccs 抄送人
         */
        public MailHelper addCc(Collection<String> ccs) {
            this.ccs.addAll(ccs);
            return this;
        }

        /**
         * 添加附件
         *
         * @param name 附件名
         * @param path 附件本地路径
         */
        public MailHelper addAttachment(String name, String path) {
            return addAttachment(name, new File(path));
        }

        /**
         * 添加附件
         *
         * @param name 附件名
         * @param file 附件文件
         */
        public MailHelper addAttachment(String name, File file) {
            this.attachments.put(name, new FileSystemResource(file));
            return this;
        }

        /**
         * 添加附件
         *
         * @param name  附件名
         * @param bytes 附件数据
         */
        public MailHelper addAttachment(String name, byte[] bytes) {
            return addAttachment(name, new ByteArrayInputStream(bytes));
        }

        /**
         * 添加附件
         *
         * @param name        附件名
         * @param inputStream 文件流
         */
        public MailHelper addAttachment(String name, InputStream inputStream) {
            this.attachments.put(name, () -> inputStream);
            return this;
        }

        /**
         * 添加内联资源
         *
         * @param name 文件名
         * @param path 文件本地路径
         */
        public MailHelper addInline(String name, String path) {
            return addInline(name, new File(path));
        }

        /**
         * 添加内联资源
         *
         * @param name 文件名
         * @param file 文件
         */
        public MailHelper addInline(String name, File file) {
            this.inlines.put(name, new FileSystemResource(file));
            return this;
        }

        /**
         * 添加内联资源
         *
         * @param name  文件名
         * @param bytes 文件数据
         */
        public MailHelper addInline(String name, byte[] bytes) {
            this.inlines.put(name, new ByteArrayResource(bytes));
            return this;
        }

        /**
         * 添加内联资源
         *
         * @param name        文件名
         * @param inputStream 文件流
         */
        public MailHelper addInline(String name, InputStream inputStream) {
            this.inlines.put(name, new InputStreamResource(inputStream));
            return this;
        }

    }

    public static class MailSender {

        private MailHelper mailHelper;

        MailSender(MailHelper mailHelper) {
            this.mailHelper = mailHelper;
        }

        public void send() throws MessagingException {
            MimeMessage message = getMailSender().createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            // 设置📧发送方
            helper.setFrom(sender);
            // 设置📧接收方
            helper.setTo(mailHelper.receivers.toArray(new String[0]));
            // 设置📧抄送方
            helper.setCc(mailHelper.ccs.toArray(new String[0]));
            // 设置📧主题
            helper.setSubject(mailHelper.subject);
            // 设置📧内容
            helper.setText(mailHelper.content, mailHelper.html);
            // 添加📧附件
            for (String name : mailHelper.attachments.keySet()) {
                helper.addAttachment(name, mailHelper.attachments.get(name));
            }
            // 添加📧内联元素
            for (String name : mailHelper.inlines.keySet()) {
                helper.addInline(name, mailHelper.inlines.get(name));
            }
            log.info("给 {} 发送邮件 `{}` 成功", String.join(",", mailHelper.receivers), mailHelper.subject);
            // 发送📧
            mailSender.send(message);
        }
    }


}

文章作者: Emil
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Emil !
评论
 上一篇
Nginx内置变量 Nginx内置变量
使用 nginx 服务器时,一定会用到 nginx 内置变量,必须需要获取客户端请求的真实域名/IPnamedescription$arg_name请求中的的参数名,即?后面的 arg_name=arg_value$args请求中的参数值$
2019-10-04
下一篇 
SpringCloud-Eureka基础篇 SpringCloud-Eureka基础篇
1. Eureka 简介本博客来自阅读《重新定义Spring Cloud实战》Eureka是 Netflix 的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与
2019-10-01
  目录