package com.fjhx.email.utils; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.fjhx.email.entity.dto.MailboxInfo; import com.fjhx.email.entity.dto.ObsFile; import com.fjhx.email.entity.dto.SendDto; import com.fjhx.email.entity.vo.MessageDetailVo; import com.fjhx.email.enums.MailFlagEnum; import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; import com.sun.mail.smtp.SMTPMessage; import com.sun.mail.util.MailSSLSocketFactory; import lombok.SneakyThrows; import javax.activation.DataHandler; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.*; public class EmailUtil { private static final Properties properties; private static final Session session; private static final HashMap storeId = new HashMap<>(); static { properties = new Properties(); // 开启ssl properties.put("mail.imap.ssl.enable", true); // 套接字连接超时值(毫秒)。此超时由java.net.Socket实现。默认是无限超时。 properties.put("mail.imap.connectiontimeout", 1000 * 60); // 套接字读取超时值(毫秒)。此超时由java.net.Socket实现。默认是无限超时。 properties.put("mail.imap.timeout", 1000 * 60); // 套接字写超时值,单位为毫秒。此超时是通过使用java.util.concurrent实现的。 // ScheduledExecutorService每个连接,调度线程在超时过期时关闭套接字。 // 因此,使用此超时的开销是每个连接一个线程。默认是无限超时。 properties.put("mail.imap.writetimeout", 1000 * 60); session = Session.getInstance(properties); storeId.put("name", "fjhx"); storeId.put("version", "1.0"); storeId.put("vendor", "fjhxClient"); storeId.put("support-email", "fjhx@fjhx.com"); } // @SneakyThrows // public static void main(String[] args) { // MailboxInfo mailboxInfo = new MailboxInfo(); // mailboxInfo.setReceiveHost("imap.gmail.com"); // mailboxInfo.setReceivePort(993); // mailboxInfo.setMailUser("y2428241269@gmail.com"); // mailboxInfo.setMailPassword("upoujrquwweqtsuk"); // IMAPStore imapStore = getIMAPStore(mailboxInfo); // System.out.println(); // } // public static void main(String[] args) throws Exception { // ObsFile attachment = new ObsFile(); // attachment.setFileUrl("https://os.winfaster.cn/fjhx/saas/GrandStar/2023/03/08/png/3092592f2d614d83854fad5e4c107143.png"); // attachment.setFileName("board-1.png"); // SendDto.Address address = new SendDto.Address(); // address.setAddress("2428241269@qq.com"); // SendDto sendDto = new SendDto(); // sendDto.setTo(Collections.singletonList(address)); // sendDto.setFileList(Collections.singletonList(attachment)); // sendDto.setSubject("测试标题"); // sendDto.setContent("测试内容"); // sendMail("imap.qq.com", "2428241269@qq.com", "kdypajdrwfhtdihb", sendDto); // } /** * 获取imapStore * 993 */ public static IMAPStore getIMAPStore(MailboxInfo mailboxInfo) throws MessagingException { IMAPStore store = (IMAPStore) session.getStore("imap"); store.connect( mailboxInfo.getReceiveHost(), mailboxInfo.getReceivePort(), mailboxInfo.getMailUser(), mailboxInfo.getMailPassword()); store.id(storeId); return store; } /** * 获取收件人、抄送人、密送人、回复人 */ @SneakyThrows public static List mailAddressList(Message message) { Address[] to = message.getRecipients(Message.RecipientType.TO); Address[] cc = message.getRecipients(Message.RecipientType.CC); Address[] bcc = message.getRecipients(Message.RecipientType.BCC); Address[] replyTo = message.getReplyTo(); List mailAddressList = new ArrayList<>(); addMailAddressList(mailAddressList, to, 1); addMailAddressList(mailAddressList, cc, 2); addMailAddressList(mailAddressList, bcc, 3); addMailAddressList(mailAddressList, replyTo, 4); return mailAddressList; } /** * 获取标签 */ public static String getFlags(Flags flags) { if (flags == null) { return StringPool.EMPTY; } Flags.Flag[] systemFlags = flags.getSystemFlags(); if (systemFlags.length == 0) { return StringPool.EMPTY; } StringJoiner stringJoiner = new StringJoiner(","); for (Flags.Flag systemFlag : systemFlags) { stringJoiner.add(MailFlagEnum.getType(systemFlag)); } return stringJoiner.toString(); } /** * 获取邮箱文件夹 */ public static List getFolderNameList(IMAPStore imapStore) throws MessagingException { IMAPFolder folder = (IMAPFolder) imapStore.getDefaultFolder(); Folder[] folders = folder.list(); List mailFolderList = new ArrayList<>(); addMailFolderList(mailFolderList, folders); return mailFolderList; } /** * 发送邮件 */ public static void sendMail(String host, String user, String password, SendDto sendDto) throws Exception { // QQ存在一个特性设置SSL加密 MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); // 创建一个配置文件并保存 Properties properties = new Properties(); properties.put("mail.host", host); properties.put("mail.user", user); properties.put("mail.password", password); properties.put("mail.transport.protocol", "smtp"); properties.put("mail.smtp.auth", true); properties.put("mail.smtp.ssl.enable", true); properties.put("mail.smtp.ssl.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 创建一个session对象 Session session = Session.getInstance(properties); // 获取连接对象 Transport transport = session.getTransport(); // 创建邮件对象 SMTPMessage mimeMessage = new SMTPMessage(session); // 邮件发送人 mimeMessage.setFrom(new InternetAddress(user)); List to = sendDto.getTo(); if (ObjectUtil.isNotEmpty(to)) { mimeMessage.setRecipients(Message.RecipientType.TO, getAddresses(to)); } List cc = sendDto.getCc(); if (ObjectUtil.isNotEmpty(cc)) { mimeMessage.setRecipients(Message.RecipientType.CC, getAddresses(cc)); } List bcc = sendDto.getBcc(); if (ObjectUtil.isNotEmpty(bcc)) { mimeMessage.setRecipients(Message.RecipientType.BCC, getAddresses(bcc)); } List replyTo = sendDto.getReplyTo(); if (ObjectUtil.isNotEmpty(replyTo)) { mimeMessage.setReplyTo(getAddresses(replyTo)); } // 邮件标题 mimeMessage.setSubject(sendDto.getSubject()); // 邮件内容大对象 MimeMultipart mimeMultipart = new MimeMultipart(); // 对象内添加正文 BodyPart content = new MimeBodyPart(); content.setContent(sendDto.getContent(), "text/html;charset=UTF-8"); mimeMultipart.addBodyPart(content); // 对象内添加邮件 List fileList = sendDto.getFileList(); if (ObjectUtil.isNotEmpty(fileList)) { for (ObsFile attachment : fileList) { DataHandler dataHandler = new DataHandler(new URL(attachment.getFileUrl())); MimeBodyPart mimeBodyPart = new MimeBodyPart(); mimeBodyPart.setDataHandler(dataHandler); mimeBodyPart.setContentID(IdWorker.getIdStr()); mimeBodyPart.setFileName(MimeUtility.encodeText(attachment.getFileName())); mimeMultipart.addBodyPart(mimeBodyPart); } } // 添加邮件内容 mimeMessage.setContent(mimeMultipart); // 连接服务器 transport.connect(host, user, password); // 发送邮件 transport.sendMessage(mimeMessage, new Address[]{new InternetAddress(user)}); // 关闭连接 transport.close(); } private static void addMailAddressList(List mailAddressList, Address[] addresses, Integer type) { if (addresses == null) { return; } for (Address address : addresses) { InternetAddress internetAddress = (InternetAddress) address; MessageDetailVo.MessageAddress mailAddress = new MessageDetailVo.MessageAddress(); mailAddress.setType(type); mailAddress.setEmail(internetAddress.getAddress()); mailAddress.setPersonalName(internetAddress.getPersonal()); mailAddressList.add(mailAddress); } } private static InternetAddress[] getAddresses(List addressList) throws UnsupportedEncodingException { InternetAddress[] internetAddresses = new InternetAddress[addressList.size()]; for (int i = 0; i < addressList.size(); i++) { InternetAddress internetAddress = new InternetAddress(); internetAddress.setPersonal(addressList.get(i).getPersonal(), "utf-8"); internetAddress.setAddress(addressList.get(i).getAddress()); internetAddresses[i] = internetAddress; } return internetAddresses; } private static void addMailFolderList(List mailFolderList, Folder[] folders) throws MessagingException { for (Folder folder : folders) { int type = folder.getType(); if (type == 2) { addMailFolderList(mailFolderList, folder.list()); } else if (type == 3) { mailFolderList.add(folder.getFullName()); } } } }