源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

一、说明

1.1 项目结构说明

  1. 邮件发送配置类为com.heibaiying.config下EmailConfig.java;
  2. 简单邮件发送、附件邮件发送、内嵌资源邮件发送、模板邮件发送的方法封装在SpringMail类中;
  3. 项目以单元测试的方法进行测试,测试类为SendEmail。

1.2 依赖说明

除了spring的基本依赖外,需要导入邮件发送的支持包spring-context-support

 <!--邮件发送依赖包-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring-base-version}</version>
</dependency>
 <!--模板引擎-->
        <!--这里采用的是beetl,beetl性能很卓越并且功能也很全面 官方文档地址 <a href="http://ibeetl.com/guide/#beetl">-->
<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>2.9.7</version>
</dependency>

二、spring email

2.1 邮件发送配置

/**
 * @author : heibaiying
 * @description : 邮件发送配置类
 */

@Configuration
@ComponentScan(value = "com.heibaiying.email")
public class EmailConfig {

    /***
     * 在这里可以声明不同的邮件服务器主机,通常是SMTP主机,而具体的用户名和时授权码则建议在业务中从数据库查询
     */
    @Bean(name = "qqMailSender")
    JavaMailSenderImpl javaMailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost("smtp.qq.com");
        javaMailSender.setPassword("587");
        return javaMailSender;
    }

    /***
     * 配置模板引擎
     */
    @Bean
    GroupTemplate groupTemplate() throws IOException {
        //指定加载模板资源的位置 指定在classpath:beetl下-
        ClasspathResourceLoader loader = new ClasspathResourceLoader("beetl");
        //beetl配置 这里采用默认的配置-
        org.beetl.core.Configuration configuration = org.beetl.core.Configuration.defaultConfiguration();
        return new GroupTemplate(loader, configuration);
    }
}

2.2 新建邮件发送基本类

/**
 * @author : heibaiying
 * @description : 邮件发送基本类
 */
@Component
public class SpringMail {

    @Autowired
    private JavaMailSenderImpl qqMailSender;
    @Autowired
    private GroupTemplate groupTemplate;

    /**
     * 发送简单邮件
     * 在qq邮件发送的测试中,测试结果表明不管是简单邮件还是复杂邮件都必须指定发送用户,
     * 且发送用户已经授权不然都会抛出异常: SMTPSendFailedException 501 mail from address must be same as authorization user
     * qq 的授权码 可以在 设置/账户/POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 中开启服务后获取
     */
    public void sendTextMessage(String from, String authWord, String to, String subject, String content) {
        // 设置发送人邮箱和授权码
        qqMailSender.setUsername(from);
        qqMailSender.setPassword(authWord);
        // 实例化消息对象
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setFrom(from);
        msg.setTo(to);
        msg.setSubject(subject);
        msg.setText(content);
        try {
            // 发送消息
            this.qqMailSender.send(msg);
            System.out.println("发送邮件成功");
        } catch (MailException ex) {
            // 消息发送失败可以做对应的处理
            System.err.println("发送邮件失败" + ex.getMessage());
        }
    }

    /**
     * 发送带附件的邮件
     */
    public void sendEmailWithAttachments(String from, String authWord, String to,
                                         String subject, String content, Map<String, File> files) {
        try {
            // 设置发送人邮箱和授权码
            qqMailSender.setUsername(from);
            qqMailSender.setPassword(authWord);
            // 实例化消息对象
            MimeMessage message = qqMailSender.createMimeMessage();
            // 需要指定第二个参数为true 代表创建支持可选文本,内联元素和附件的多部分消息
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content);
            // 传入附件
            for (Map.Entry<String, File> entry : files.entrySet()) {
                helper.addAttachment(entry.getKey(), entry.getValue());
            }
            // 发送消息
            this.qqMailSender.send(message);
            System.out.println("发送邮件成功");
        } catch (MessagingException ex) {
            // 消息发送失败可以做对应的处理
            System.err.println("发送邮件失败" + ex.getMessage());
        }
    }

    /**
     * 发送带内嵌资源的邮件
     */
    public void sendEmailWithInline(String from, String authWord, String to,
                                    String subject, String content, File file) {
        try {
            // 设置发送人邮箱和授权码
            qqMailSender.setUsername(from);
            qqMailSender.setPassword(authWord);
            // 实例化消息对象
            MimeMessage message = qqMailSender.createMimeMessage();
            // 需要指定第二个参数为true 代表创建支持可选文本,内联元素和附件的多部分消息
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            // 使用true标志来指示包含的文本是HTML 固定格式资源前缀 cid:
            helper.setText("<html><body><img src='cid:image'></body></html>", true);
            // 需要先指定文本 再指定资源文件
            FileSystemResource res = new FileSystemResource(file);
            helper.addInline("image", res);
            // 发送消息
            this.qqMailSender.send(message);
            System.out.println("发送邮件成功");
        } catch (MessagingException ex) {
            // 消息发送失败可以做对应的处理
            System.err.println("发送邮件失败" + ex.getMessage());
        }
    }

    /**
     * 使用模板邮件
     */
    public void sendEmailByTemplate(String from, String authWord, String to,
                                    String subject, String content) {
        try {
            Template t = groupTemplate.getTemplate("template.html");
            t.binding("subject", subject);
            t.binding("content", content);
            String text = t.render();
            // 设置发送人邮箱和授权码
            qqMailSender.setUsername(from);
            qqMailSender.setPassword(authWord);
            // 实例化消息对象
            MimeMessage message = qqMailSender.createMimeMessage();
            // 指定 utf-8 防止乱码
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            // 为true 时候 表示文本内容以 html 渲染
            helper.setText(text, true);
            this.qqMailSender.send(message);
            System.out.println("发送邮件成功");
        } catch (MessagingException ex) {
            // 消息发送失败可以做对应的处理
            System.err.println("发送邮件失败" + ex.getMessage());
        }
    }

}

关于模板邮件的说明:

  • 模板引擎最主要的作用是,在对邮件格式有要求的时候,采用拼接字符串不够直观,所以采用模板引擎;

  • 这里我们使用的beetl模板引擎,原因是其性能优异,官网是介绍其性能6倍与freemaker,并有完善的文档支持。当然大家也可以换成任何其他的模板引擎(freemarker,thymeleaf)

    一个简单的模板template.html如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <h1>邮件主题:<span style="color: chartreuse"> ${subject}</span></h1>
    <h4 style="color: blueviolet">${content}</h4>
</body>
</html>

2.3 邮件发送的测试

/**
 * @author : heibaiying
 * @description : 发送邮件测试类
 */
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = EmailConfig.class)
public class SendEmail {

    @Autowired
    private SpringMail springMail;

    // 发送方邮箱地址
    private static final String from = "发送方邮箱地址@qq.com";
    // 发送方邮箱地址对应的授权码
    private static final String authWord = "授权码";
    // 接收方邮箱地址
    private static final String to = "接收方邮箱地址@qq.com";

    @Test
    public void sendMessage() {

        springMail.sendTextMessage(from, authWord, to, "spring简单邮件", "Hello Spring Email!");
    }

    @Test
    public void sendComplexMessage() {
        Map<String, File> fileMap = new HashMap<>();
        fileMap.put("image1.jpg", new File("D:\\LearningNotes\\picture\\msm相关依赖.png"));
        fileMap.put("image2.jpg", new File("D:\\LearningNotes\\picture\\RabbitMQ模型架构.png"));
        springMail.sendEmailWithAttachments(from, authWord, to, "spring多附件邮件"
                , "Hello Spring Email!", fileMap);
    }

    @Test
    public void sendEmailWithInline() {
        springMail.sendEmailWithInline(from, authWord, to, "spring内嵌资源邮件"
                , "Hello Spring Email!", new File("D:\\LearningNotes\\picture\\RabbitMQ模型架构.png"));
    }

    @Test
    public void sendEmailByTemplate() {
        springMail.sendEmailByTemplate(from, authWord, to,
                "spring模板邮件", "Hello Spring Email!");
    }
}

附:源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

spring 5.x 系列第20篇 ——spring简单邮件、附件邮件、内嵌资源邮件、模板邮件发送 (代码配置方式)的更多相关文章

  1. spring 5.x 系列第19篇 ——spring简单邮件、附件邮件、内嵌资源邮件、模板邮件发送 (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 邮件发送配置文件为springApplic ...

  2. spring 5.x 系列第22篇 —— spring 定时任务 (代码配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 关于任务的调度配置定义在ServletCo ...

  3. spring 5.x 系列第21篇 —— spring 定时任务 (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 关于任务的调度配置定义在springApp ...

  4. spring 5.x 系列第4篇 —— spring AOP (代码配置方式)

    文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 2.5 切面执行顺 ...

  5. spring 5.x 系列第3篇 —— spring AOP (xml配置方式)

    文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 附: 关于切面表达 ...

  6. Mysql高手系列 - 第20篇:异常捕获及处理详解(实战经验)

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第20篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...

  7. spring 5.x 系列第2篇 —— springmvc基础 (代码配置方式)

    文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关注解说明 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...

  8. spring cloud 入门系列一:初识spring cloud

    最近看到微服务很火,也是未来的趋势, 所以就去学习下,在dubbo和spring cloud之间我选择了从spring cloud,主要有如下几种原因: dubbo主要专注于微服务中的一个环节--服务 ...

  9. Spring Boot 学习系列(序)—Spring Boot

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Spring Boot? Spring Boot 是由pivotal团队提供的一个基于Spring的全新框架 ...

随机推荐

  1. uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题

    原文:uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题 开发中碰到一个问题,当RichEditBox输入的文本达到一定行数的时候,滚动条此时位于底部,改变文本样式(如字体 ...

  2. wxWidgets编译和在VC 6.0中的配置

    1. 安装  运行wxMSW-2.8.3-Setup1.exe,将之安装到不带空格符号的目录中,本例为C:/wxWidgets-2.8.3:   2. 编译和配置 (1) 用VC6.0编译  进入C: ...

  3. Leetcode 226 Invert Binary Tree 二叉树

    交换左右叶子节点 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * ...

  4. TOP计划猿10最佳实践文章

    本文转自:EETproject教师专辑 http://forum.eet-cn.com/FORUM_POST_10011_1200263220_0.HTM?click_from=8800111934, ...

  5. VelocityTracker简要

    翻译自:http://developer.android.com/reference/android/view/VelocityTracker.html 參照自: http://blog.jrj.co ...

  6. WPF Binding Path妙用代码实现

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  7. WPF的逻辑树和视觉树

    原文:WPF的逻辑树和视觉树 这部分的内容来自于即将出版的新书<WPF Unleashed>的第三章样章.关于什么是逻辑树,我们先看下面的一个伪XAML代码的例子: <Window ...

  8. 蓝牙模块在HHARM2410上的移植

    最近两天在HHARM2410-R3上移植了USB蓝牙设备和 BlueZ 蓝牙协议栈,呵呵,蓝牙果然是个很好的东西,协议栈内容很丰富,挂上去以后可以使用很多功能.我现在就可以用它来接收 GPS 数据以及 ...

  9. How to manipulate pixels on a bitmap by scanline property(Ma Xiaoguang and Ma Xiaoming)

    We have been developing image processing software for above 14 years with old versions of Delphi, su ...

  10. UWP入门(十)--创建、写入和读取文件

    原文:UWP入门(十)--创建.写入和读取文件 核心的 API github代码 StorageFolder 类 StorageFile 类 FileIO 类 使用 StorageFile 对象读取和 ...