|
|
|
@ -0,0 +1,246 @@
|
|
|
|
|
package me.zhengjie.utils;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
|
|
import cn.hutool.core.util.CharsetUtil;
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import me.zhengjie.exception.BadRequestException;
|
|
|
|
|
|
|
|
|
|
import javax.activation.DataHandler;
|
|
|
|
|
import javax.activation.FileDataSource;
|
|
|
|
|
import javax.mail.*;
|
|
|
|
|
import javax.mail.internet.*;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.nio.file.Files;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Properties;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @author Enzo
|
|
|
|
|
* @date 2022-10-22 13:49:33
|
|
|
|
|
*/
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class MailUtil {
|
|
|
|
|
|
|
|
|
|
private MailUtil() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 结合邮件返回
|
|
|
|
|
*
|
|
|
|
|
* @param username
|
|
|
|
|
* @param password
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static List<Message> readMailByIMAP(String username, String password) {
|
|
|
|
|
List<Message> list = Lists.newArrayList();
|
|
|
|
|
Properties props = System.getProperties();
|
|
|
|
|
//设置电子邮件协议
|
|
|
|
|
props.setProperty("mail.store.protocol", "imaps");
|
|
|
|
|
try {
|
|
|
|
|
Session session = Session.getDefaultInstance(props, null);
|
|
|
|
|
Store store = session.getStore("imaps");
|
|
|
|
|
store.connect("outlook.office365.com", username, password);
|
|
|
|
|
Folder inbox = store.getFolder("Inbox");
|
|
|
|
|
inbox.open(Folder.READ_WRITE);
|
|
|
|
|
Message[] messages = inbox.getMessages();
|
|
|
|
|
list.addAll(Arrays.asList(messages));
|
|
|
|
|
} catch (NoSuchProviderException e) {
|
|
|
|
|
log.error("======================= open mail error time {} message as {} ==================", DateUtil.date(), e.getMessage());
|
|
|
|
|
throw new BadRequestException("没有找到该服务");
|
|
|
|
|
} catch (MessagingException e) {
|
|
|
|
|
log.error("======================= open mail error time {} message as {} ==================", DateUtil.date(), e.getMessage());
|
|
|
|
|
throw new BadRequestException("发送邮件失败");
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建一封复杂邮件(文本+图片+附件)
|
|
|
|
|
*/
|
|
|
|
|
public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail, String filename, String taskName) throws Exception {
|
|
|
|
|
// 1. 创建邮件对象
|
|
|
|
|
MimeMessage message = new MimeMessage(session);
|
|
|
|
|
|
|
|
|
|
// 2. From: 发件人
|
|
|
|
|
message.setFrom(new InternetAddress(sendMail, sendMail, CharsetUtil.UTF_8));
|
|
|
|
|
|
|
|
|
|
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
|
|
|
|
|
message.addRecipient(Message.RecipientType.TO, new InternetAddress(receiveMail, receiveMail, CharsetUtil.UTF_8));
|
|
|
|
|
|
|
|
|
|
// 4. Subject: 邮件主题
|
|
|
|
|
message.setSubject(taskName, CharsetUtil.UTF_8);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 下面是邮件内容的创建:
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// 6. 创建文本“节点”
|
|
|
|
|
/*MimeBodyPart text = new MimeBodyPart();
|
|
|
|
|
// 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
|
|
|
|
|
text.setContent(taskName, "text/html;charset=UTF-8");
|
|
|
|
|
|
|
|
|
|
// 7. (文本+图片)设置 文本 和 图片 “节点”的关系(将 文本 和 图片 “节点”合成一个混合“节点”)
|
|
|
|
|
MimeMultipart mmTextImage = new MimeMultipart();
|
|
|
|
|
mmTextImage.addBodyPart(text);
|
|
|
|
|
// 关联关系
|
|
|
|
|
mmTextImage.setSubType("related");
|
|
|
|
|
|
|
|
|
|
// 8. 将 文本+图片 的混合“节点”封装成一个普通“节点”
|
|
|
|
|
// 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
|
|
|
|
|
// 上面的 mm_text_image 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
|
|
|
|
|
MimeBodyPart textImage = new MimeBodyPart();
|
|
|
|
|
textImage.setContent(mmTextImage);*/
|
|
|
|
|
|
|
|
|
|
// 9. 创建附件“节点”
|
|
|
|
|
MimeBodyPart attachment = new MimeBodyPart();
|
|
|
|
|
// 读取本地文件
|
|
|
|
|
DataHandler dh2 = new DataHandler(new FileDataSource(filename));
|
|
|
|
|
// 将附件数据添加到“节点”
|
|
|
|
|
attachment.setDataHandler(dh2);
|
|
|
|
|
// 设置附件的文件名(需要编码)
|
|
|
|
|
attachment.setFileName(MimeUtility.encodeText(dh2.getName()));
|
|
|
|
|
|
|
|
|
|
// 10. 设置(文本+图片)和 附件 的关系(合成一个大的混合“节点” / Multipart )
|
|
|
|
|
MimeMultipart mm = new MimeMultipart();
|
|
|
|
|
// mm.addBodyPart(textImage);
|
|
|
|
|
// 如果有多个附件,可以创建多个多次添加
|
|
|
|
|
mm.addBodyPart(attachment);
|
|
|
|
|
// 混合关系
|
|
|
|
|
mm.setSubType("mixed");
|
|
|
|
|
|
|
|
|
|
// 11. 设置整个邮件的关系(将最终的混合“节点”作为邮件的内容添加到邮件对象)
|
|
|
|
|
message.setContent(mm);
|
|
|
|
|
|
|
|
|
|
// 12. 设置发件时间
|
|
|
|
|
message.setSentDate(new Date());
|
|
|
|
|
|
|
|
|
|
// 13. 保存上面的所有设置
|
|
|
|
|
message.saveChanges();
|
|
|
|
|
|
|
|
|
|
return message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Boolean sendMail(String username, String password, String toUsername, String fileName, String taskName) {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
|
|
|
|
|
// 参数配置
|
|
|
|
|
Properties props = new Properties();
|
|
|
|
|
|
|
|
|
|
// 端口
|
|
|
|
|
props.put("mail.smtp.port", "587");
|
|
|
|
|
|
|
|
|
|
// 发件人的邮箱的 SMTP 服务器地址
|
|
|
|
|
props.put("mail.smtp.host", "smtp.office365.com");
|
|
|
|
|
|
|
|
|
|
// 当前smtp host设为可信任 否则抛出javax.mail.MessagingException: Could not convert socket to TLS
|
|
|
|
|
props.put("mail.smtp.ssl.trust", "smtp.office365.com");
|
|
|
|
|
|
|
|
|
|
// 使用的协议(JavaMail规范要求)
|
|
|
|
|
props.put("mail.transport.protocol", "smtp");
|
|
|
|
|
|
|
|
|
|
// 需要请求认证
|
|
|
|
|
props.put("mail.smtp.auth", "true");
|
|
|
|
|
|
|
|
|
|
// 开启STARTTLS
|
|
|
|
|
props.put("mail.smtp.starttls.enable", "true");
|
|
|
|
|
|
|
|
|
|
// ssl
|
|
|
|
|
props.put("mail.smtp.ssl", "true");
|
|
|
|
|
|
|
|
|
|
// 开启 SSL 连接, 以及更详细的发送步骤请看上一篇: 基于 JavaMail 的 Java 邮件发送:简单邮件发送
|
|
|
|
|
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
|
|
|
|
|
Session session = Session.getInstance(props);
|
|
|
|
|
// 设置为debug模式, 可以查看详细的发送 log
|
|
|
|
|
session.setDebug(Boolean.FALSE);
|
|
|
|
|
|
|
|
|
|
// 3. 创建一封邮件
|
|
|
|
|
MimeMessage message = createMimeMessage(session, username, toUsername, fileName, taskName);
|
|
|
|
|
|
|
|
|
|
// 4. 根据 Session 获取邮件传输对象
|
|
|
|
|
Transport transport = session.getTransport();
|
|
|
|
|
|
|
|
|
|
// 5. 使用 邮箱账号 和 密码 连接邮件服务器
|
|
|
|
|
// 这里认证的邮箱必须与 message 中的发件人邮箱一致,否则报错
|
|
|
|
|
transport.connect(username, password);
|
|
|
|
|
|
|
|
|
|
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
|
|
|
|
|
transport.sendMessage(message, message.getAllRecipients());
|
|
|
|
|
|
|
|
|
|
// 7. 关闭连接
|
|
|
|
|
transport.close();
|
|
|
|
|
return Boolean.TRUE;
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
log.error("===================== send message error {} ==========================", ex.getMessage());
|
|
|
|
|
return Boolean.FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static boolean sendEmail(String sender, String password, String host, String port, String receiver,String subject,String content) {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
Properties props = new Properties();
|
|
|
|
|
// 开启debug调试
|
|
|
|
|
props.setProperty("mail.debug", "false");
|
|
|
|
|
// 发送服务器需要身份验证
|
|
|
|
|
props.setProperty("mail.smtp.auth", "true");
|
|
|
|
|
// 设置邮件服务器主机名
|
|
|
|
|
props.setProperty("mail.host", host);
|
|
|
|
|
// 发送邮件协议名称 这里使用的是smtp协议
|
|
|
|
|
props.setProperty("mail.transport.protocol", "smtp");
|
|
|
|
|
// 服务端口号
|
|
|
|
|
props.setProperty("mail.smtp.port", port);
|
|
|
|
|
props.put("mail.smtp.starttls.enable", "true");
|
|
|
|
|
|
|
|
|
|
// 设置环境信息
|
|
|
|
|
Session session = Session.getInstance(props);
|
|
|
|
|
|
|
|
|
|
// 创建邮件对象
|
|
|
|
|
MimeMessage msg = new MimeMessage(session);
|
|
|
|
|
|
|
|
|
|
// 设置发件人
|
|
|
|
|
msg.setFrom(new InternetAddress(sender));
|
|
|
|
|
|
|
|
|
|
// 设置收件人
|
|
|
|
|
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
|
|
|
|
|
|
|
|
|
|
// 设置邮件主题
|
|
|
|
|
msg.setSubject(subject);
|
|
|
|
|
|
|
|
|
|
// 设置邮件内容
|
|
|
|
|
Multipart multipart = new MimeMultipart();
|
|
|
|
|
|
|
|
|
|
MimeBodyPart textPart = new MimeBodyPart();
|
|
|
|
|
//发送邮件的文本内容
|
|
|
|
|
textPart.setText(content);
|
|
|
|
|
multipart.addBodyPart(textPart);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg.setContent(multipart);
|
|
|
|
|
|
|
|
|
|
Transport transport = session.getTransport();
|
|
|
|
|
// 连接邮件服务器
|
|
|
|
|
transport.connect(sender, password);
|
|
|
|
|
// 发送邮件
|
|
|
|
|
transport.sendMessage(msg, new Address[]{new InternetAddress(receiver)});
|
|
|
|
|
// 关闭连接
|
|
|
|
|
transport.close();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|