springboot发送邮件【完整详细 Demo】

2023-12-24 17:02:42

(因为想创建一个干净的空白邮箱作为测试,所以这里用163网易邮箱为例【 网易邮箱 注册简单,可实验性高】)

一、开启邮箱服务

1、在首页的设置里面开启【POP3/SMTP】服务
在这里插入图片描述

2、 需要验证账号安全,可以用微信扫码,快速发送短信
在这里插入图片描述
3、开启后 会给一个授权密码,这个时候需要把密码拷贝下来【授权码只显示一次】
在这里插入图片描述
4、在刚刚开启服务的下方可以管理授权码的【设备名称、启用时间和删除操作】
在这里插入图片描述

二、导入项目依赖

    <!-- 发送邮件所需依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>

    <!--使用Thymeleaf模板引擎(邮件发送模板)-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

三、 配置 application.yml 文件

spring:
  mail:
    protocol: smtp                   # 邮件协议
    host: smtp.163.com               # smtp 服务器地址 (163邮箱为例)
    port: 25                         # 端口号(163邮箱为例)
    username: 邮箱@163.com            # 发送人邮箱地址
    password: XXX前面的授权码XXX       # 授权码
    default-encoding: utf-8          # 编码字符集
    debug: true                      # 开启debug模式用户会完整打印邮件发送过程的日志

四、实现service


import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.net.URISyntaxException;
import java.util.Date;


/**
 * 发送邮件:【模板邮件、附件邮件、普通邮件】的简单实现
 * @author 北海&南风
 * @since 2023-12-24
 */

@Service
public class MailService {

    @Value("${spring.mail.username}")
    private String mailUsername;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private TemplateEngine templateEngine;


    /**
     * 发送模板模板
     * @param email 收件人邮箱
     */
    public void sendMailForTemplateEngine(String email){

        //创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

            //设置邮件主题
            message.setSubject("测试模板邮件");

            //设置邮箱发送者
            message.setFrom(mailUsername);

            //设置邮件接受者,可以多个 eg : message.setTo(new String[]{"email1","email2"})   !!!群发如果有一个邮箱是错误的,则整体发送失败!!!
            message.setTo(email);

            //设置邮件抄送人,可以多个 【所有的收件人和抄送人都可以看到邮件发送给了哪些邮箱以及抄送给了哪些邮箱。】
            message.setCc(mailUsername);

            //设置隐秘抄送人,可以多个 【收件人和抄送人不会看到你密送的邮箱,隐私性更强】
            message.setBcc(mailUsername);

            //设置邮件发送日期
            message.setSentDate(new Date());

            /**
             * 并不是定时发送邮件。
             * 如果你设置的发送日期是未来的五分钟,那么邮件的发送日期将显示为未来的五分钟。
             * 但是这并不意味着邮件会在未来的五分钟后发送,因为邮件的实际发送时间是由邮件服务器决定的,而不是由setSentDate方法决定的。(设置过去的时间也同理)
             * 【所以你可以给”过去“或者”未来“发送一份邮件(邮件的排序是根据时间来排序的,设置时间,理论上 可以使你的邮件”置顶“或”置底“)】
             * 【!不是所有的邮件服务器都适用!
             * 1. qq邮箱会强制使用当前时间,而忽略你设置的。
             * 2. 163邮箱设置当天内的时间有效,设置其他时间会被强制会当前时间(2023-12-24)】
             */

            //创建上下文环境
            Context context= new Context();
            context.setVariable("variable1","测试跳转百度");
            context.setVariable("variable2","https://www.baidu.com");
            String text = templateEngine.process("test.html",context);

            /**
             * 【Thymeleaf模板文件默认存放在src/main/resources/templates/目录下】
             *  可以在配置中更改目录,eg:spring.thymeleaf.prefix=classpath:/html/
             * 【解释:将Thymeleaf模板文件的路径改为src/main/resources/html。!路径的值最后一定要加上斜杠/,否则就会出错!】
            */


            //设置邮件正文
            message.setText(text,true);

        } catch (MessagingException e) {
            e.printStackTrace();
        }
        //邮件发送
        javaMailSender.send(mimeMessage);
    }




    /**
     * 发送附件邮件
     * @param email 收件人邮箱
     */
    public void sendMailForAttachment(String email){

        //创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

            message.setSubject("测试附件邮件");
            message.setFrom(mailUsername);
            message.setTo(email);
            message.setSentDate(new Date());
            message.setText("<h1>这是一个带了附件的邮件!!!</h1>",true);

            String filePath = this.getClass().getResource("/attachment/imgTest.png").toURI().getPath();
            if (StringUtils.hasText(filePath)) {
                FileSystemResource file = new FileSystemResource(new File(filePath));
                String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                message.addAttachment(fileName,file);
            }
            /**
             * 真实场景,可能不是一个固定文件,而需要由前端传入文件或base64转文件等方式。根据上面代码自己灵活变通 转为File类型即可。
            */

        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        //邮件发送
        javaMailSender.send(mimeMessage);
    }


    /**
     * 发送普通邮件
     * @param email 收件人邮箱
     */
    public void sendMailForText(String email){

        //创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

            message.setSubject("测试普通邮件");
            message.setFrom(mailUsername);
            message.setTo(email);
            message.setSentDate(new Date());
            message.setText("这是一个普通文字邮件!!!");
//            message.setText("<h1>这是一个带了HTML格式邮件!!!</h1>",true);

        } catch (MessagingException e) {
            e.printStackTrace();
        }
        //邮件发送
        javaMailSender.send(mimeMessage);
    }

}

五、测试邮件发送


import 上面第四步的service.MailService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;



@SpringBootTest
class SendEmailApplicationTests {

	@Autowired
	private MailService mailService;

	private String email = "接受者邮箱@qq.com";
	
//	测试模板邮件发送
	@Test
	void sendMailForTemplateEngine() {
		mailService.sendMailForTemplateEngine(email);
	}
	
//	测试附件邮件发送
	@Test
	void sendMailForAttachment() {
		mailService.sendMailForAttachment(email);
	}
	
//	测试普通文件发送
	@Test
	void sendMailForText() {
		mailService.sendMailForText(email);
	}

}

项目目录展示

在这里插入图片描述

效果展示

在这里插入图片描述

完整项目下载

CSDN下载,可能需少量积分,感谢支持!

没积分?白嫖?那三连后:百度网盘下载
.
提取码:6688

拓展

什么是POP3、SMTP及IMAP?

POP3
?????POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。

SMTP
?????SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
?????SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。
?????增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。

IMAP
?????IMAP全称是Internet Mail Access Protocol,即交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一。不同的是,开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留 在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端 软件登录邮箱,看到的邮件以及状态都是一致的。

》邮箱 端口号有哪些,代表什么作用(场景)

SMTP服务器的端口号主要有以下几种,它们在不同的场景下有不同的作用:

  • 端口25:这是SMTP服务器之间连接最常用的端口,主要用于邮件服务器到邮件服务器的通信。然而,现在许多网络的防火墙通常会阻止这个端口,因为垃圾邮件发送者试图滥用它来发送大量垃圾邮件。
  • 端口587:这是电子邮件提交的默认端口,经过该端口的SMTP通信使用TLS加密。这个端口主要应用于提交,即邮件客户端到邮件服务器的通信。
  • 端口465:这个端口曾经专门用于具备安全套接字层(SSL)加密的SMTP,但现在已经过时,应尽可能使用端口587。然而,这个端口在一些传统(过时)的系统中仍然被使用。
  • 端口994:这个端口通常用于IMAP协议的加密版本,即IMAPS。当IMAP协议通过SSL/TLS加密时,就会使用这个端口。这样可以确保在客户端和服务器之间传输的邮件数据的安全性。
  • 端口2525:这个端口与SMTP没有正式关联,但在上述端口被堵塞的情况下,某些电子邮件服务通过这个端口提供SMTP传输。

》这个Demo(邮件发送)能做什么

1、 注册辅助激活、忘记密码辅助找回密码
2、 给用户群发通知邮箱【入职,公告等】
3、 发送预警消息邮件【检测状态,如果服务器性能爆了,或者服务器掉线 则邮件通知管理员处理】
4、 采用定时任务,发送提醒消息邮件
… …

》不想要163邮箱,想用其他邮箱发送行不行

只需要在第一步开启邮箱POP3服务后,在更改application.yml 配置文件即可 (例如qq邮箱)

host: smtp.qq.com               # smtp 服务器地址 (163邮箱为例)
port: 587                         # 端口号(163邮箱为例)
username: 邮箱@qq.com            # 发送人邮箱地址
password: XXX前面的授权码XXX       # 授权码

》 为什么本地能发送邮箱,但是部署到服务器(阿里云)上就不可以了

阿里云服务器上需要开启 ssl 认证连接,在application.yml 配置文件下增加配置,开启一个安全的SMTP连接:

spring:
 mail:
   properties:
     mail:
       smtp:
         ssl:
           trust: smtp.163.com
         socketFactory:
           class: javax.net.ssl.SSLSocketFactory
           port: 465
         auth: true
         starttls:
           enable: true
           required: true

.properties格式:

spring.mail.properties.mail.smtp.ssl.trust=smtp.163.com
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

文章来源:https://blog.csdn.net/weixin_46157208/article/details/135180726
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。