基于SpringBoot实现邮件发送

1.引言

现实中的邮件发送,比如A写信给B,A写好信,送到当地邮局,邮局会给他信封,在信封上贴邮票,写收发人及地址;然后邮局会根据信封上的信息把送B所在地的邮局,再通知B去当地指定邮局取信。模拟这个过程,电子邮件的发送类似,邮局就好比电子邮件的的邮箱服务器,A和B就相当于邮箱服务器的客户端。这样一来,邮件发送的过程归结为以下3步:

第一步:发件人把邮件信息放到发件人邮箱服务器。

第二步:基于邮件协议(SMTP), 把发件人邮箱服务器的邮件信息发送到收件人的邮箱服务器。

第三步:收件人到收件人邮箱服务器获取邮件信息。

2.邮件协议

在邮件服务器中 ,涉及三种协议SMTP, POP3, IMAP。

总体上看,SMTP负债邮件的发送, POP3和IMAP负债邮件的收取.

SMTP(Simple Mail Transfer Protocol)协议是一种简单邮件传输协议(默认端口是25),属于互联网一种通讯方式,基于TCP/IP协议实现。主要负责邮件服务器之间的传递,比如网易SMTP服务器向腾讯SMTP发送,它是要求通过用户和密码进行认证登录,才可以进行传递。

POP3(Post Office Protocol 3)协议是邮局协议(默认端口110),是支持客户端从服务器上进行管理邮件,比如把邮件存储到本地主机,同时删除保存在邮件服务器上的邮件。值得注意的是,客户端的操作(比如移动,标记等)不会影响服务器的操作。

IMAP(Internet Mail Access Protocol)协议是交互式邮件协议(默认端口143),该协议也是用来客户端从服务器获取邮件的协议,与POP3不同的是,在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如删除,标记等。

3.实现

3.1 创建SpringBoot项目,添加邮件相关配置的参数

  • 首先创建一个SpringBoot项目,进入官网https://start.spring.io/,记得加入web和mail依赖

在这里插入图片描述

  • 在application.properties添加配置
#发件人邮件服务器地址
spring.mail.host=smtp.163.com
#发件人邮件服务器端口
spring.mail.port=465
#发件人邮件登录用户
spring.mail.username=jerome_wzy@163.com
#发件人邮件登录授权码
spring.mail.password=BWWREEWSEBGSSKU
#邮件登录字符集编码
spring.mail.default-encoding=UTF-8
#邮件发送的加密方式
spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactory
#是否开启SSL访问邮件服务器
spring.mail.properties.mail.smtp.ssl.enable=true
#邮件发送的调试模式,打开后查看邮件发送的详细日志
spring.mail.properties.mail.debug=true

其中邮件登录的授权码可以通过邮件客户端的设置选项,开启SMTP服务后,根据提示通过发送短信的方式进行生成。

在这里插入图片描述

启动SpringBoot项目,spring-boot-autoconfigure会自动配置我们刚才的添加的参数,其中注解@EnableConfigurationProperties({MailProperties.class}) 正是为了加载配置的参数,部分源码如下:

package org.springframework.boot.autoconfigure.mail;

@Configuration
@ConditionalOnClass({MimeMessage.class, MimeType.class, MailSender.class})
@ConditionalOnMissingBean({MailSender.class})
@Conditional({MailSenderAutoConfiguration.MailSenderCondition.class})
@EnableConfigurationProperties({MailProperties.class})
@Import({MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class})
public class MailSenderAutoConfiguration {
    public MailSenderAutoConfiguration() {
    }
@ConfigurationProperties(
    prefix = "spring.mail"
)
public class MailProperties {
    private static final Charset DEFAULT_CHARSET;
    private String host;
    private Integer port;
    private String username;
    private String password;
    private String protocol = "smtp";
    private Charset defaultEncoding;
    private Map<String, String> properties;
    private String jndiName;

    public MailProperties() {
        this.defaultEncoding = DEFAULT_CHARSET;
        this.properties = new HashMap();
    }

3.2 实现文本,附件及内嵌资源的邮件发送

创建简单的邮件对象SimpleMailMessage, 实现邮件文本的发送

@Test
public void sendSimpleMail() {
    SimpleMailMessage emailMsg = new SimpleMailMessage();
    //邮件主题
    emailMsg.setSubject("简单邮件主题");
    //发件人
    emailMsg.setFrom("jerome_wzy@163.com");
    //收件人
    emailMsg.setTo("461402931@qq.com");
    //抄送人
    emailMsg.setCc("xxxxx1@qq.com");
    //密送人
    emailMsg.setBcc("xxxxx2@qq.com");
    //发送日志
    emailMsg.setSentDate(new Date());
    //文本正文
    emailMsg.setText("这是测试邮件的正文文本");

    //发送邮件
    javaMailSender.send(emailMsg);
}

发送结果如下:

在这里插入图片描述

  • 创建附件进行邮件发送, 此时需要创建邮件的较为复杂的对象MimeMessage,通过MimeMessageHelper设置相关属性,完成邮件发送
@Test
public void sendAttachMail() {
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    try {
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,true);
        //邮件主题
        mimeMessageHelper.setSubject("附件邮件主题");
        //发件人
        mimeMessageHelper.setFrom("jerome_wzy@163.com");
        //收件人
        mimeMessageHelper.setTo("461402931@qq.com");
        //抄送人
        //mimeMessageHelper.setCc("xxxxx1@qq.com");
        //密送人
        //mimeMessageHelper.setBcc("xxxxx2@qq.com");
        //发送日志
        mimeMessageHelper.setSentDate(new Date());
        //文本正文
        mimeMessageHelper.setText("附件邮件正文");

        //添加附件
        File file = new File("E:\\git\\git_src\\SpringBoot-learning-samples\\Emails-2.png");
        mimeMessageHelper.addAttachment("Emails-2.png",file);
        //发送邮件
        javaMailSender.send(mimeMessage);
    } catch (MessagingException e) {
        e.printStackTrace();
    }

}

发送结果如下:

在这里插入图片描述

使用内嵌资源进行邮件发送

@Test
public void sendResourceMail() {
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();

    try {
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,true);
    //邮件主题
    mimeMessageHelper.setSubject("内嵌资源邮件主题");
    //发件人
    mimeMessageHelper.setFrom("jerome_wzy@163.com");
    //收件人
    mimeMessageHelper.setTo("461402931@qq.com");
    //发送日志
    mimeMessageHelper.setSentDate(new Date());
    //内嵌资源时,注意设置文本属性时,通过cid先占位,然后在设置图片
    mimeMessageHelper.setText("<html><body><p>图片显示如下:</p><img src='cid:context-id123'></body></html>", true);

    //添加附件
    File file = new File("E:\\git\\git_src\\SpringBoot-learning-samples\\Emails-2.png");
    mimeMessageHelper.addInline("context-id123",file);
    //发送邮件
    javaMailSender.send(mimeMessage);
    } catch (MessagingException e) {
    e.printStackTrace();
    }

}

发送结果如下:这里注意的是内嵌资源时,必须先设置setText给资源占位,然后设置资源,顺序弄反将无法内嵌资源。

在这里插入图片描述

3.3 使用模板发送邮件

  • 使用FreeMarker作为邮件模板发送

FreeMarker是一种模板引擎,基于模板和要改变的数据,并用来生成输出文本(比如HTML网页)的通用工具。

在项目中添加FreeMarker依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

在templates目录下编写ftl模板:

<!DOCTYPE html>
<html>
<head> 
    <meta charset="utf-8"> 
    <title>会议信息</title> 
</head>
<body>
<h4>会议信息:</h4>
<ol>
    <li>会议名称: ${meetName}</li>
    <li>会议主持人: ${meetUser}</li>
    <li>会议时间: ${meetDate}</li>
</ol>
</body>
</html>

定义一个会议DTO,用来设置相关的会议信息。开始渲染模板,发送邮件

@Test
public void sendFreemarkerMail() throws MessagingException, IOException, TemplateException {
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
    mimeMessageHelper.setSubject("FreeMarker邮件主题");
    mimeMessageHelper.setFrom("jerome_wzy@163.com");
    mimeMessageHelper.setTo("461402931@qq.com");
    mimeMessageHelper.setSentDate(new Date());
    //Freemarker配置
    Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
    // 加载模板位置,这里父类层级使用springBoot默认的templates
    ClassLoader classLoader = EmailsApplication.class.getClassLoader();
    configuration.setClassLoaderForTemplateLoading(classLoader, "templates");
    //加载模板
    Template template = configuration.getTemplate("meeting.ftl");
    Meeting meeting = new Meeting();
    meeting.setMeetName("关于市政停车位收费的讨论会议");
    meeting.setMeetUser("jerome");
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    meeting.setMeetDate(simpleDateFormat.format(new Date()));
    StringWriter out = new StringWriter();
    template.process(meeting, out);
    //模板渲染
    mimeMessageHelper.setText(out.toString(),true);
    javaMailSender.send(mimeMessage);
}

发送邮件,结果如下:

在这里插入图片描述

  • 使用模板引擎Thymeleaf发送邮件

Thymeleaf是一种动静结合的,可以直接在浏览器中打开并正确显示模板页面。 在有网络和无网络的环境下皆可运行,这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。

在项目中添加的Thymeleaf的依赖:

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

在templates目录下编写模板:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head> 
    <meta charset="utf-8"> 
    <title>会议信息</title> 
</head>
<body>
<h4 th:text="会议信息:"/>
<ol>
    <!--/*@thymesVar id="meetName" type="templates"*/-->
    <li th:text="'会议名称:' + ${meetName}"/>
    <!--/*@thymesVar id="meetUser" type="templates"*/-->
    <li th:text="'会议主持人:' + ${meetUser}"/>
    <!--/*@thymesVar id="meetDate" type="templates"*/-->
    <li th:text="'会议时间:' + ${meetDate}"/>
</ol>
</body>
</html>

由于thymeleaf是springBoot官方推荐的模板引擎,所以实现自动化配置,不需要我们单独加载模板。只需要使用thymeleaf提供的TemplateEngine可以完成模板渲染。

@Autowired
private TemplateEngine templateEngine;

@Test
public void sendMailWithThyemeleaf() throws MessagingException, IOException, TemplateException {
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
    mimeMessageHelper.setSubject("Thyemeleaf邮件主题");
    mimeMessageHelper.setFrom("jerome_wzy@163.com");
    mimeMessageHelper.setTo("461402931@qq.com");
    mimeMessageHelper.setSentDate(new Date());

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    org.thymeleaf.context.Context context = new org.thymeleaf.context.Context();

    context.setVariable("meetName", "关于市政停车位收费的讨论会议");
    context.setVariable("meetUser","jerome");
    context.setVariable("meetDate", simpleDateFormat.format(new Date()));
    String process = templateEngine.process("meeting.html", context);
    mimeMessageHelper.setText(process,true);

    javaMailSender.send(mimeMessage);
}

发送邮件,结果如下:

在这里插入图片描述

4 结语

基于SringBoot实现的邮件发送就介绍到这里了,实际使用中的邮件发送大多是采用模板来完成,这样可以实现显示和数据逻辑的分离,便于修改维护。


项目地址: https://github.com/jerome2018/SpringBoot-learning-samples

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值