目录
1.邮件协议:
POP3 接收邮件协议(邮局协议),端口:110 SLL 加密类型端口:995。
IMAP 接收邮件协议(交互式邮件存取协议),端口:114 SLL 加密类型端口:993。
SMTP 发送邮件协议(简单邮件传输协议)。端口:25。用于在客户端发送邮件,无论
使用那种接收协议都需要使用 SMTP 协议发送邮件。一般是 smtp.xxx.com
2.集成步骤:
-
添加依赖
<!--邮件发送-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
-
yaml中配置邮件信息
本次采用的的阿里邮箱,所以host为:smtp.mxhichina.com,,配置信息时,需要将相应的邮箱补充完整。
spring:
profiles:
active: test
mail:
default-encoding: UTF-8
host: smtp.mxhichina.com
username: 发件人邮箱
password: XXX #密码
protocol: smtp
properties:
mail:
smtp:
port: 25
to: 接收人邮箱
cc: 抄送人邮箱
bcc: 密送人邮箱
-
代码编写
控制层
package com.test.controller;
import com.test.core.response.ApiResponse;
import com.test.model.MailReq;
import com.test.service.EmailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
* @ClassName: EmailController
* @description: 邮件发送
* @author: yz
* @create: 2021-12-16 14:42
* @Version 1.0
*/
@RestController
@RequestMapping("/email")
@Api("邮件管理api")
@Validated
public class EmailController {
@Autowired
private EmailService emailService;
@PostMapping("/sendHtmlMail")
@ApiOperation(value="发送HTML邮件", notes="发送HTML邮件")
public ApiResponse<Boolean> sendHtmlMail(@RequestBody @Valid MailReq data ){
return ApiResponse.requestSuccess(emailService.sendHtmlMail(data));
}
}
实现层
发送内容主要进行文本文字。
package com.test.service.impl;
import com.test.entity.EmailEntity;
import com.test.model.MailReq;
import com.test.service.EmailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/**
* @ClassName: EmailServiceImpl
* @description: 邮件发送实现类
* @author: yz
* @create: 2021-12-16 14:47
* @Version 1.0
*/
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
/**
* 用于发送文件
*/
@Resource
private JavaMailSender mailSender;
@Autowired
private EmailEntity emailEntity;
@Override
public Boolean sendHtmlMail(MailReq mailReq) {
log.info("发送HTML邮件开始:{}", mailReq);
//使用MimeMessage,MIME协议
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper;
//MimeMessageHelper帮助我们设置更丰富的内容
try {
helper = new MimeMessageHelper(message, true);
helper.setFrom(emailEntity.getFrom());
helper.setTo(emailEntity.getTo().split(","));
helper.setCc(emailEntity.getCc().split(","));
helper.setBcc(emailEntity.getBcc().split(","));
//主题
helper.setSubject("邮件测试");
//true代表支持html
helper.setText(contentConvertHtml(mailReq), true);
mailSender.send(message);
log.info("发送HTML邮件成功");
} catch ( MessagingException e) {
log.error("发送HTML邮件失败:", e);
}
return true;
}
private String contentConvertHtml(MailReq mailReq) {
String content = mailReq.getContent();
StringBuilder rs = new StringBuilder();
String pStr = "<p style=\"font-size: 14px;font-weight:bold;color:#4D4D4D;\">";
rs.append(pStr + "姓名: " + content + "</p>");
rs.append(pStr + "本邮件由小程序用户触发发送。</p>");
return rs.toString();
}
}
读取配置类
package com.test.entity;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @ClassName: EmailEntity
* @description: 邮件配置
* @author: yz
* @create: 2021-12-16 14:58
* @Version 1.0
*/
@Component
@Data
@ConfigurationProperties(prefix = "spring.mail")
public class EmailEntity {
//发送者
@Value("${spring.mail.username}")
private String from;
//收件者
private String to;
//抄送者
private String cc;
//密送人
private String bcc;
}
-
结果展示
3.基于JavaMail的Java邮件发送
xml添加的依赖不变以及配置邮件信息不变,和步骤2相同。
-
实现类代码
此方法包含发送文本文字、附件、图片等功能。
package com.test.service.impl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.util.Date;
import java.util.Properties;
/**
* @ClassName: Email2ServiceImpl
* @description: 邮件发送实现方式2
* @author: yz
* @create: 2021-12-16 16:07
* @Version 1.0
*/
@Component
public class Email2ServiceImpl {
@Value("${spring.mail.username}")
public String myEmailAccount ;
@Value("${spring.mail.password}")
public String myEmailPassword;
// 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com
// 网易163邮箱的 SMTP 服务器地址为: smtp.163.com
@Value("${spring.mail.host}")
public String myEmailSMTPHost ;
// 收件人邮箱(替换为自己知道的有效邮箱)
@Value("${spring.mail.to}")
public String receiveMailAccount;
public Boolean senEmail2() throws Exception {
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties props = new Properties(); // 参数配置
props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
props.setProperty("mail.smtp.host", myEmailSMTPHost); // 发件人的邮箱的 SMTP 服务器地址
props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(props);
session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log
// 3. 创建一封邮件
MimeMessage message = createMimeMessage(session, myEmailAccount, receiveMailAccount);
// 4. 根据 Session 获取邮件传输对象
Transport transport = session.getTransport();
// 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
transport.connect(myEmailAccount, myEmailPassword);
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 关闭连接
transport.close();
return true;
}
/**
* 创建一封只包含文本的简单邮件
*
* @param session 和服务器交互的会话
* @param sendMail 发件人邮箱
* @param receiveMail 收件人邮箱
* @return
* @throws Exception
*/
public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail) throws Exception {
// 1. 创建一封邮件
MimeMessage message = new MimeMessage(session);
// 2. From: 发件人(昵称有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改昵称)
message.setFrom(new InternetAddress(sendMail, "某宝网", "UTF-8"));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "XX用户", "UTF-8"));
// 4. Subject: 邮件主题(标题有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改标题)
message.setSubject("打折钜惠", "UTF-8");
// 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容)
message.setContent("XX用户你好, 今天全场5折, 快来抢购, 错过今天再等一年。。。", "text/html;charset=UTF-8");
// 6. 设置发件时间
message.setSentDate(new Date());
// 7. 保存设置
message.saveChanges();
return message;
}
/**
* 创建一封复杂邮件(文本+图片+附件)
*/
public static MimeMessage createMimeMessage2(Session session, String sendMail, String receiveMail) throws Exception {
// 1. 创建邮件对象
MimeMessage message = new MimeMessage(session);
// 2. From: 发件人
message.setFrom(new InternetAddress(sendMail, "我的测试邮件_发件人昵称", "UTF-8"));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
message.addRecipient(Message.RecipientType.TO, new InternetAddress(receiveMail, "我的测试邮件_收件人昵称", "UTF-8"));
// 4. Subject: 邮件主题
message.setSubject("TEST邮件主题(文本+图片+附件)", "UTF-8");
/*
* 下面是邮件内容的创建:
*/
// 5. 创建图片“节点”
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("FairyTail.jpg")); // 读取本地文件
image.setDataHandler(dh); // 将图片数据添加到“节点”
image.setContentID("image_fairy_tail"); // 为“节点”设置一个唯一编号(在文本“节点”将引用该ID)
// 6. 创建文本“节点”
MimeBodyPart text = new MimeBodyPart();
// 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
text.setContent("这是一张图片<br/><img src='cid:image_fairy_tail'/>", "text/html;charset=UTF-8");
// 7. (文本+图片)设置 文本 和 图片 “节点”的关系(将 文本 和 图片 “节点”合成一个混合“节点”)
MimeMultipart mm_text_image = new MimeMultipart();
mm_text_image.addBodyPart(text);
mm_text_image.addBodyPart(image);
mm_text_image.setSubType("related"); // 关联关系
// 8. 将 文本+图片 的混合“节点”封装成一个普通“节点”
// 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
// 上面的 mm_text_image 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
MimeBodyPart text_image = new MimeBodyPart();
text_image.setContent(mm_text_image);
// 9. 创建附件“节点”
MimeBodyPart attachment = new MimeBodyPart();
DataHandler dh2 = new DataHandler(new FileDataSource("妖精的尾巴目录.doc")); // 读取本地文件
attachment.setDataHandler(dh2); // 将附件数据添加到“节点”
attachment.setFileName(MimeUtility.encodeText(dh2.getName())); // 设置附件的文件名(需要编码)
// 10. 设置(文本+图片)和 附件 的关系(合成一个大的混合“节点” / Multipart )
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text_image);
mm.addBodyPart(attachment); // 如果有多个附件,可以创建多个多次添加
mm.setSubType("mixed"); // 混合关系
// 11. 设置整个邮件的关系(将最终的混合“节点”作为邮件的内容添加到邮件对象)
message.setContent(mm);
// 12. 设置发件时间
message.setSentDate(new Date());
// 13. 保存上面的所有设置
message.saveChanges();
return message;
}
}