一,SMTP简介
SMTP服务器是一种专门用于发送电子邮件的互联网服务器。SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)是一种用于电子邮件传输的标准互联网协议。这些服务器充当电子邮件的“邮递员”,负责将发出的邮件从发送者传输到接收者的邮箱。
让我们通过一个例子来更好地理解SMTP服务器的工作原理:
示例:A发送电子邮件给B
A编写邮件:A在他的电子邮件客户端(如Outlook、Gmail网页版等)上撰写一封邮件,准备发送给B。
邮件发送至SMTP服务器:当A点击“发送”按钮时,他的邮件客户端会将邮件发送到预先配置好的SMTP服务器。假设A使用的是Gmail,那么这封邮件会被发送到Google的SMTP服务器(smtp.gmail.com)。
SMTP服务器处理邮件:Google的SMTP服务器接收到这封邮件后,会首先验证A的身份(确保他是该邮箱的合法用户),然后根据邮件中的收件人地址,决定下一步的传输路径。
邮件传输到收件人的服务器:SMTP服务器确定B的邮箱地址对应的服务器。例如,如果B使用的是163邮箱,Google的SMTP服务器会将邮件发送到163的服务器。
邮件存储在收件人的邮箱中:一旦邮件到达163的服务器,它将被存储在B的邮箱中,等待他登录邮箱进行查看。
重要特点:
只用于发送邮件:SMTP服务器仅用于发送邮件,不处理接收邮件的功能。接收邮件通常由另一种协议处理,如POP3或IMAP。
需要正确的配置:为了通过SMTP服务器发送邮件,用户需要在他们的邮件客户端中正确配置SMTP服务器的地址、端口、用户名和密码。
安全性:为了保障邮件传输的安全性,现代的SMTP服务器通常支持诸如SS=L/TLS等加密协议。
涉及邮件其它几个协议
POP3协议:邮局协议版本3(Post Office Protocol - Version 3),将邮件从服务器下载下来,服务器端邮件删除
IMAP协议:邮件访问协议(Internet Mail Access Protocol),将邮件从服务器下载下来,服务器端邮件保留,并且和客户端状态保持一致
Mime协议:多用途互联网邮件扩展类型(Multipurpose Internet Mail Extensions),使二进制传输变简单
二,邮件发送过程几个协议的协作关系
SMTP协议主要负责邮件的发送。当用户通过邮件客户端软件(如Outlook、Foxmail等)编写好邮件并点击发送按钮后,SMTP协议就会被激活。邮件客户端软件会连接到邮件服务器,使用SMTP协议将邮件发送出去。SMTP协议确保邮件在传输过程中是可靠且有效的,它会处理邮件的封装、传输和路由等问题,确保邮件能够准确送达目标邮件服务器。
POP3和IMAP协议则主要负责邮件的接收。当用户想要查看或下载邮件时,邮件客户端软件会使用POP3或IMAP协议连接到邮件服务器。POP3协议将邮件从服务器下载到本地计算机,这样用户就可以在自己的计算机上查看邮件了。而IMAP协议则允许用户直接在服务器上查看和管理邮件,用户不需要下载邮件到本地计算机就可以进行查看、删除、移动等操作。IMAP协议还提供了邮件检索和邮件处理的新功能,用户可以完全不必下载邮件正文就可以看到邮件的标题摘要,从邮件客户端软件就可以对服务器上的邮件和文件夹目录等进行操作。
在整个邮件发送和接收过程中,这些协议之间的作用相互关联、协同工作。SMTP协议负责将邮件从发送方发送到接收方的邮件服务器,而POP3或IMAP协议则负责将邮件从服务器下载到用户的计算机或直接在服务器上查看和管理邮件。这些协议共同保证了电子邮件的可靠传输和有效管理,使得用户能够方便地使用电子邮件进行沟通和交流。
此外,邮件发送过程中还涉及到其他的技术和组件,如DNS(域名系统)用于解析邮件地址中的域名,确定邮件服务器的地址;邮件服务器负责存储和管理用户的邮件,提供邮件发送和接收的服务;以及用户代理(如邮件客户端软件)提供用户与邮件服务器之间的交互界面等。这些技术和组件与SMTP、POP和IMAP等协议一起,共同构成了电子邮件系统的完整工作流程。
三, Mailu部署
这里没有使用网上大多教程使用腾讯和网易的邮箱服务器,申请它们的授权。而是自己要搭建一个邮箱服务器。在公司中使用内网开发,服务器也不允许访问外网,所以不能向网上大多教程一样,用其它公司的邮箱服务器进行发送邮件开发。而选择使用这种方案。
Mailu部署大家可以参考这边文章,我这里就不Ctrl+c了。
文章地址
四,代码实现邮件发送
maven
<!-- 邮箱 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Mail类型
package com.zwxict.common.mail;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
/**
* @author 汤义
* @create 2024-03-10:51
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Mail {
@Pattern(regexp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$", message = "邮箱格式不正确")
private String to;
@NotBlank(message = "标题不能为空")
private String title;
@NotBlank(message = "正文不能为空")
private String content;
private String msgId;// 消息id
}
MailUtil类型
package com.zwxict.common.mail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
/**
* 邮箱发送工具
* @author 汤义
* @create 2024-03-10:55
*/
@Component
@Slf4j
public class MailUtil {
/**
* 发件人
*/
@Value("${spring.mail.from}")
private String from;
@Autowired
private JavaMailSender mailSender;
/**
* 发送简单邮件
*
* @param mail
*/
public boolean send(Mail mail) {
String to = mail.getTo();// 目标邮箱
String title = mail.getTitle();// 邮件标题
String content = mail.getContent();// 邮件正文
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(title);
message.setText(content);
try {
mailSender.send(message);
log.info("邮件发送成功");
return true;
} catch (MailException e) {
log.error("邮件发送失败, to: {}, title: {}", to, title, e);
return false;
}
}
/**
* 发送附件邮件
*
* @param mail 邮件
* @param file 附件
*/
public boolean sendAttachment(Mail mail, File file) {
String to = mail.getTo();
String title = mail.getTitle();
String content = mail.getContent();
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(title);
helper.setText(content);
FileSystemResource resource = new FileSystemResource(file);
String fileName = file.getName();
helper.addAttachment(fileName, resource);
mailSender.send(message);
log.info("附件邮件发送成功");
return true;
} catch (Exception e) {
log.error("附件邮件发送失败, to: {}, title: {}", to, title, e);
return false;
}
}
/**
* 发送html
*/
public boolean sendHTML(Mail mail){
String to = mail.getTo();// 目标邮箱
String title = mail.getTitle();// 邮件标题
String content = mail.getContent();// 邮件正文
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper;
try {
helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(title);//主题
mimeMessage.setContent(content, "text/html ;charset=gbk");
mailSender.send(mimeMessage);
log.info("邮件发送成功");
return true;
} catch (MessagingException e1) {
log.error("邮件发送失败, to: {}, title: {}", to, title, e1);
return false;
}
}
}
application.yml配置
spring:
#邮箱配置
#平台地址,这里用的是qq邮箱,使用其他邮箱请更换
mail:
host: XXXXXX # 如何在部署Mailu时没有配置DNS,那么这里就是服务器ip
port: 25
protocol: smtp # 邮件协议
#发送邮件的邮箱地址:改成自己的邮箱
username: XXXXXX
#邮箱密码
password: XXXXX
#与发件邮箱一致
from: XXXXXX
default-encoding: utf-8 # 编码字符集
properties:
mail:
smtp:
auth: true # 使用
starttls: # 使用 SSL 安全协议,须如下配置
enable: true