diff --git a/hutool-extra/src/main/java/cn/hutool/extra/mail/Mail.java b/hutool-extra/src/main/java/cn/hutool/extra/mail/Mail.java
index b225f299d..08620a92b 100644
--- a/hutool-extra/src/main/java/cn/hutool/extra/mail/Mail.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/mail/Mail.java
@@ -1,354 +1,388 @@
-package cn.hutool.extra.mail;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.Date;
-
-import javax.activation.DataHandler;
-import javax.activation.DataSource;
-import javax.activation.FileDataSource;
-import javax.mail.Authenticator;
-import javax.mail.BodyPart;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.StrUtil;
-
-/**
- * 邮件发送客户端
- *
- * @author looly
- * @since 3.2.0
- */
-public class Mail {
-
- /** 邮箱帐户信息以及一些客户端配置信息 */
- private MailAccount mailAccount;
- /** 收件人列表 */
- private String[] tos;
- /** 抄送人列表(carbon copy) */
- private String[] ccs;
- /** 密送人列表(blind carbon copy) */
- private String[] bccs;
- /** 回复地址(reply-to) */
- private String[] reply;
- /** 标题 */
- private String title;
- /** 内容 */
- private String content;
- /** 是否为HTML */
- private boolean isHtml;
- /** 附件列表 */
- private DataSource[] attachments;
- /** 是否使用全局会话,默认为false */
- private boolean useGlobalSession = false;
-
- /**
- * 创建邮件客户端
- *
- * @param mailAccount 邮件帐号
- * @return {@link Mail}
- */
- public static Mail create(MailAccount mailAccount) {
- return new Mail(mailAccount);
- }
-
- /**
- * 创建邮件客户端,使用全局邮件帐户
- *
- * @return {@link Mail}
- */
- public static Mail create() {
- return new Mail();
- }
-
- // --------------------------------------------------------------- Constructor start
- /**
- * 构造,使用全局邮件帐户
- */
- public Mail() {
- this(GlobalMailAccount.INSTANCE.getAccount());
- }
-
- /**
- * 构造
- *
- * @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
- */
- public Mail(MailAccount mailAccount) {
- mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
- this.mailAccount = mailAccount.defaultIfEmpty();
- }
- // --------------------------------------------------------------- Constructor end
-
- // --------------------------------------------------------------- Getters and Setters start
- /**
- * 设置收件人
- *
- * @param tos 收件人列表
- * @return this
- * @see #setTos(String...)
- */
- public Mail to(String... tos) {
- return setTos(tos);
- }
-
- /**
- * 设置多个收件人
- *
- * @param tos 收件人列表
- * @return this
- */
- public Mail setTos(String... tos) {
- this.tos = tos;
- return this;
- }
-
- /**
- * 设置多个抄送人(carbon copy)
- *
- * @param ccs 抄送人列表
- * @return this
- * @since 4.0.3
- */
- public Mail setCcs(String... ccs) {
- this.ccs = ccs;
- return this;
- }
-
- /**
- * 设置多个密送人(blind carbon copy)
- *
- * @param bccs 密送人列表
- * @return this
- * @since 4.0.3
- */
- public Mail setBccs(String... bccs) {
- this.bccs = bccs;
- return this;
- }
-
- /**
- * 设置多个回复地址(reply-to)
- *
- * @param reply 回复地址(reply-to)列表
- * @return this
- * @since 4.6.0
- */
- public Mail setReply(String... reply) {
- this.reply = reply;
- return this;
- }
-
- /**
- * 设置标题
- *
- * @param title 标题
- * @return this
- */
- public Mail setTitle(String title) {
- this.title = title;
- return this;
- }
-
- /**
- * 设置正文
- *
- * @param content 正文
- * @return this
- */
- public Mail setContent(String content) {
- this.content = content;
- return this;
- }
-
- /**
- * 设置是否是HTML
- *
- * @param isHtml 是否为HTML
- * @return this
- */
- public Mail setHtml(boolean isHtml) {
- this.isHtml = isHtml;
- return this;
- }
-
- /**
- * 设置文件类型附件
- *
- * @param files 附件文件列表
- * @return this
- */
- public Mail setFiles(File... files) {
- if(ArrayUtil.isEmpty(files)) {
- return this;
- }
-
- final DataSource[] attachments = new DataSource[files.length];
- for (int i = 0; i < files.length; i++) {
- attachments[i] = new FileDataSource(files[i]);
- }
- return setAttachments(attachments);
- }
-
- /**
- * 设置附件,附件使用{@link DataSource} 形式表示,可以使用{@link FileDataSource}包装文件表示文件附件
- *
- * @param attachments 附件列表
- * @return this
- * @since 4.0.9
- */
- public Mail setAttachments(DataSource... attachments) {
- if(ArrayUtil.isNotEmpty(attachments)) {
- this.attachments = attachments;
- }
- return this;
- }
-
- /**
- * 设置字符集编码
- *
- * @param charset 字符集编码
- * @return this
- * @see MailAccount#setCharset(Charset)
- */
- public Mail setCharset(Charset charset) {
- this.mailAccount.setCharset(charset);
- return this;
- }
-
- /**
- * 设置是否使用全局会话,默认为true
- *
- * @param isUseGlobalSession 是否使用全局会话,默认为true
- * @return this
- * @since 4.0.2
- */
- public Mail setUseGlobalSession(boolean isUseGlobalSession) {
- this.useGlobalSession = isUseGlobalSession;
- return this;
- }
- // --------------------------------------------------------------- Getters and Setters end
-
- /**
- * 发送
- *
- * @return this
- * @throws MailException 邮件发送异常
- */
- public Mail send() throws MailException {
- try {
- return doSend();
- } catch (MessagingException e) {
- throw new MailException(e);
- }
- }
-
- // --------------------------------------------------------------- Private method start
- /**
- * 执行发送
- *
- * @return this
- * @throws MessagingException 发送异常
- */
- private Mail doSend() throws MessagingException {
- Transport.send(buildMsg());
- return this;
- }
-
- /**
- * 构建消息
- *
- * @return {@link MimeMessage}消息
- * @throws MessagingException 消息异常
- */
- private MimeMessage buildMsg() throws MessagingException {
- final Charset charset = this.mailAccount.getCharset();
- final MimeMessage msg = new MimeMessage(getSession(this.useGlobalSession));
- // 发件人
- final String from = this.mailAccount.getFrom();
- if (StrUtil.isEmpty(from)) {
- // 用户未提供发送方,则从Session中自动获取
- msg.setFrom();
- } else {
- msg.setFrom(InternalMailUtil.parseFirstAddress(from, charset));
- }
- // 标题
- msg.setSubject(this.title, charset.name());
- // 发送时间
- msg.setSentDate(new Date());
- // 内容和附件
- msg.setContent(buildContent(charset));
- // 收件人
- msg.setRecipients(MimeMessage.RecipientType.TO, InternalMailUtil.parseAddressFromStrs(this.tos, charset));
- // 抄送人
- if (ArrayUtil.isNotEmpty(this.ccs)) {
- msg.setRecipients(MimeMessage.RecipientType.CC, InternalMailUtil.parseAddressFromStrs(this.ccs, charset));
- }
- // 密送人
- if (ArrayUtil.isNotEmpty(this.bccs)) {
- msg.setRecipients(MimeMessage.RecipientType.BCC, InternalMailUtil.parseAddressFromStrs(this.bccs, charset));
- }
- // 回复地址(reply-to)
- if (ArrayUtil.isNotEmpty(this.reply)) {
- msg.setReplyTo(InternalMailUtil.parseAddressFromStrs(this.reply, charset));
- }
-
- return msg;
- }
-
- /**
- * 构建邮件信息主体
- *
- * @param charset 编码
- * @return 邮件信息主体
- * @throws MessagingException 消息异常
- */
- private Multipart buildContent(Charset charset) throws MessagingException {
- final Multipart mainPart = new MimeMultipart();
-
- // 正文
- final BodyPart body = new MimeBodyPart();
- body.setContent(content, StrUtil.format("text/{}; charset={}", isHtml ? "html" : "plain", charset));
- mainPart.addBodyPart(body);
-
- // 附件
- if (ArrayUtil.isNotEmpty(this.attachments)) {
- BodyPart bodyPart;
- for (DataSource attachment : attachments) {
- bodyPart = new MimeBodyPart();
- bodyPart.setDataHandler(new DataHandler(attachment));
- bodyPart.setFileName(InternalMailUtil.encodeText(attachment.getName(), charset));
- mainPart.addBodyPart(bodyPart);
- }
- }
-
- return mainPart;
- }
-
- /**
- * 获取默认邮件会话
- * 如果为全局单例的会话,则全局只允许一个邮件帐号,否则每次发送邮件会新建一个新的会话
- *
- * @param isSingleton 是否使用单例Session
- * @return 邮件会话 {@link Session}
- * @since 4.0.2
- */
- private Session getSession(boolean isSingleton) {
- final MailAccount mailAccount = this.mailAccount;
- Authenticator authenticator = null;
- if (mailAccount.isAuth()) {
- authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
- }
-
- return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
- : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
- }
- // --------------------------------------------------------------- Private method end
-}
+package cn.hutool.extra.mail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.Date;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.mail.Authenticator;
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 邮件发送客户端
+ *
+ * @author looly
+ * @since 3.2.0
+ */
+public class Mail {
+
+ /** 邮箱帐户信息以及一些客户端配置信息 */
+ private MailAccount mailAccount;
+ /** 收件人列表 */
+ private String[] tos;
+ /** 抄送人列表(carbon copy) */
+ private String[] ccs;
+ /** 密送人列表(blind carbon copy) */
+ private String[] bccs;
+ /** 回复地址(reply-to) */
+ private String[] reply;
+ /** 标题 */
+ private String title;
+ /** 内容 */
+ private String content;
+ /** 是否为HTML */
+ private boolean isHtml;
+ /** 附件列表 */
+ private DataSource[] attachments;
+ /** 图片列表 */
+ private Map imageMap;
+ /** 是否使用全局会话,默认为false */
+ private boolean useGlobalSession = false;
+
+ /**
+ * 创建邮件客户端
+ *
+ * @param mailAccount 邮件帐号
+ * @return {@link Mail}
+ */
+ public static Mail create(MailAccount mailAccount) {
+ return new Mail(mailAccount);
+ }
+
+ /**
+ * 创建邮件客户端,使用全局邮件帐户
+ *
+ * @return {@link Mail}
+ */
+ public static Mail create() {
+ return new Mail();
+ }
+
+ // --------------------------------------------------------------- Constructor start
+ /**
+ * 构造,使用全局邮件帐户
+ */
+ public Mail() {
+ this(GlobalMailAccount.INSTANCE.getAccount());
+ }
+
+ /**
+ * 构造
+ *
+ * @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
+ */
+ public Mail(MailAccount mailAccount) {
+ mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
+ this.mailAccount = mailAccount.defaultIfEmpty();
+ }
+ // --------------------------------------------------------------- Constructor end
+
+ // --------------------------------------------------------------- Getters and Setters start
+ /**
+ * 设置收件人
+ *
+ * @param tos 收件人列表
+ * @return this
+ * @see #setTos(String...)
+ */
+ public Mail to(String... tos) {
+ return setTos(tos);
+ }
+
+ /**
+ * 设置多个收件人
+ *
+ * @param tos 收件人列表
+ * @return this
+ */
+ public Mail setTos(String... tos) {
+ this.tos = tos;
+ return this;
+ }
+
+ /**
+ * 设置多个抄送人(carbon copy)
+ *
+ * @param ccs 抄送人列表
+ * @return this
+ * @since 4.0.3
+ */
+ public Mail setCcs(String... ccs) {
+ this.ccs = ccs;
+ return this;
+ }
+
+ /**
+ * 设置多个密送人(blind carbon copy)
+ *
+ * @param bccs 密送人列表
+ * @return this
+ * @since 4.0.3
+ */
+ public Mail setBccs(String... bccs) {
+ this.bccs = bccs;
+ return this;
+ }
+
+ /**
+ * 设置多个回复地址(reply-to)
+ *
+ * @param reply 回复地址(reply-to)列表
+ * @return this
+ * @since 4.6.0
+ */
+ public Mail setReply(String... reply) {
+ this.reply = reply;
+ return this;
+ }
+
+ /**
+ * 设置标题
+ *
+ * @param title 标题
+ * @return this
+ */
+ public Mail setTitle(String title) {
+ this.title = title;
+ return this;
+ }
+
+ /**
+ * 设置正文
+ *
+ * @param content 正文
+ * @return this
+ */
+ public Mail setContent(String content) {
+ this.content = content;
+ return this;
+ }
+
+ /**
+ * 设置是否是HTML
+ *
+ * @param isHtml 是否为HTML
+ * @return this
+ */
+ public Mail setHtml(boolean isHtml) {
+ this.isHtml = isHtml;
+ return this;
+ }
+
+ /**
+ * 设置文件类型附件
+ *
+ * @param files 附件文件列表
+ * @return this
+ */
+ public Mail setFiles(File... files) {
+ if(ArrayUtil.isEmpty(files)) {
+ return this;
+ }
+
+ final DataSource[] attachments = new DataSource[files.length];
+ for (int i = 0; i < files.length; i++) {
+ attachments[i] = new FileDataSource(files[i]);
+ }
+ return setAttachments(attachments);
+ }
+
+ /**
+ * 设置附件,附件使用{@link DataSource} 形式表示,可以使用{@link FileDataSource}包装文件表示文件附件
+ *
+ * @param attachments 附件列表
+ * @return this
+ * @since 4.0.9
+ */
+ public Mail setAttachments(DataSource... attachments) {
+ if(ArrayUtil.isNotEmpty(attachments)) {
+ this.attachments = attachments;
+ }
+ return this;
+ }
+
+ /**
+ * 设置图片,图片的键对应到邮件模板中的占位字符串
+ *
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ */
+ public Mail setImageMap(Map imageMap) {
+ if (imageMap != null && imageMap.size() > 0) {
+ this.imageMap = imageMap;
+ }
+ return this;
+ }
+
+ /**
+ * 设置字符集编码
+ *
+ * @param charset 字符集编码
+ * @return this
+ * @see MailAccount#setCharset(Charset)
+ */
+ public Mail setCharset(Charset charset) {
+ this.mailAccount.setCharset(charset);
+ return this;
+ }
+
+ /**
+ * 设置是否使用全局会话,默认为true
+ *
+ * @param isUseGlobalSession 是否使用全局会话,默认为true
+ * @return this
+ * @since 4.0.2
+ */
+ public Mail setUseGlobalSession(boolean isUseGlobalSession) {
+ this.useGlobalSession = isUseGlobalSession;
+ return this;
+ }
+ // --------------------------------------------------------------- Getters and Setters end
+
+ /**
+ * 发送
+ *
+ * @return this
+ * @throws MailException 邮件发送异常
+ */
+ public Mail send() throws MailException {
+ try {
+ return doSend();
+ } catch (MessagingException e) {
+ throw new MailException(e);
+ }
+ }
+
+ // --------------------------------------------------------------- Private method start
+ /**
+ * 执行发送
+ *
+ * @return this
+ * @throws MessagingException 发送异常
+ */
+ private Mail doSend() throws MessagingException {
+ Transport.send(buildMsg());
+ return this;
+ }
+
+ /**
+ * 构建消息
+ *
+ * @return {@link MimeMessage}消息
+ * @throws MessagingException 消息异常
+ */
+ private MimeMessage buildMsg() throws MessagingException {
+ final Charset charset = this.mailAccount.getCharset();
+ final MimeMessage msg = new MimeMessage(getSession(this.useGlobalSession));
+ // 发件人
+ final String from = this.mailAccount.getFrom();
+ if (StrUtil.isEmpty(from)) {
+ // 用户未提供发送方,则从Session中自动获取
+ msg.setFrom();
+ } else {
+ msg.setFrom(InternalMailUtil.parseFirstAddress(from, charset));
+ }
+ // 标题
+ msg.setSubject(this.title, charset.name());
+ // 发送时间
+ msg.setSentDate(new Date());
+ // 内容和附件
+ msg.setContent(buildContent(charset));
+ // 收件人
+ msg.setRecipients(MimeMessage.RecipientType.TO, InternalMailUtil.parseAddressFromStrs(this.tos, charset));
+ // 抄送人
+ if (ArrayUtil.isNotEmpty(this.ccs)) {
+ msg.setRecipients(MimeMessage.RecipientType.CC, InternalMailUtil.parseAddressFromStrs(this.ccs, charset));
+ }
+ // 密送人
+ if (ArrayUtil.isNotEmpty(this.bccs)) {
+ msg.setRecipients(MimeMessage.RecipientType.BCC, InternalMailUtil.parseAddressFromStrs(this.bccs, charset));
+ }
+ // 回复地址(reply-to)
+ if (ArrayUtil.isNotEmpty(this.reply)) {
+ msg.setReplyTo(InternalMailUtil.parseAddressFromStrs(this.reply, charset));
+ }
+
+ return msg;
+ }
+
+ /**
+ * 构建邮件信息主体
+ *
+ * @param charset 编码
+ * @return 邮件信息主体
+ * @throws MessagingException 消息异常
+ */
+ private Multipart buildContent(Charset charset) throws MessagingException {
+ final Multipart mainPart = new MimeMultipart();
+
+ // 正文
+ final BodyPart body = new MimeBodyPart();
+ body.setContent(content, StrUtil.format("text/{}; charset={}", isHtml ? "html" : "plain", charset));
+ mainPart.addBodyPart(body);
+
+ // 附件
+ if (ArrayUtil.isNotEmpty(this.attachments)) {
+ BodyPart bodyPart;
+ for (DataSource attachment : attachments) {
+ bodyPart = new MimeBodyPart();
+ bodyPart.setDataHandler(new DataHandler(attachment));
+ bodyPart.setFileName(InternalMailUtil.encodeText(attachment.getName(), charset));
+ mainPart.addBodyPart(bodyPart);
+ }
+ }
+
+ // 图片
+ for (Map.Entry entry : imageMap.entrySet()) {
+ BodyPart messageBodyPart = new MimeBodyPart();
+ DataSource ds;
+ try {
+ ds = new ByteArrayDataSource(entry.getValue(), "image/jpeg");
+ } catch (IOException e) {
+ throw new MailException(e);
+ }
+
+ messageBodyPart.setDataHandler(new DataHandler(ds));
+ messageBodyPart.setHeader("Content-ID", String.format("<%s>", entry.getKey()));
+ // add it
+ mainPart.addBodyPart(messageBodyPart);
+ }
+
+ return mainPart;
+ }
+
+ /**
+ * 获取默认邮件会话
+ * 如果为全局单例的会话,则全局只允许一个邮件帐号,否则每次发送邮件会新建一个新的会话
+ *
+ * @param isSingleton 是否使用单例Session
+ * @return 邮件会话 {@link Session}
+ * @since 4.0.2
+ */
+ private Session getSession(boolean isSingleton) {
+ final MailAccount mailAccount = this.mailAccount;
+ Authenticator authenticator = null;
+ if (mailAccount.isAuth()) {
+ authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
+ }
+
+ return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
+ : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
+ }
+ // --------------------------------------------------------------- Private method end
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/mail/MailUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/mail/MailUtil.java
index bb54fd5f3..25481863b 100644
--- a/hutool-extra/src/main/java/cn/hutool/extra/mail/MailUtil.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/mail/MailUtil.java
@@ -1,236 +1,382 @@
-package cn.hutool.extra.mail;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.StrUtil;
-
-/**
- * 邮件工具类,基于javax.mail封装
- *
- * @author looly
- * @since 3.1.2
- */
-public class MailUtil {
-
- /**
- * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
- * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
- *
- * @param to 收件人
- * @param subject 标题
- * @param content 正文
- * @param files 附件列表
- * @since 3.2.0
- */
- public static void sendText(String to, String subject, String content, File... files) {
- send(to, subject, content, false, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
- * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
- *
- * @param to 收件人
- * @param subject 标题
- * @param content 正文
- * @param files 附件列表
- * @since 3.2.0
- */
- public static void sendHtml(String to, String subject, String content, File... files) {
- send(to, subject, content, true, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
- * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
- *
- * @param to 收件人
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML
- * @param files 附件列表
- */
- public static void send(String to, String subject, String content, boolean isHtml, File... files) {
- send(splitAddress(to), subject, content, isHtml, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
- * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
- *
- * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
- * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
- * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML
- * @param files 附件列表
- * @since 4.0.3
- */
- public static void send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
- send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送文本邮件,发送给多人
- *
- * @param tos 收件人列表
- * @param subject 标题
- * @param content 正文
- * @param files 附件列表
- */
- public static void sendText(Collection tos, String subject, String content, File... files) {
- send(tos, subject, content, false, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送HTML邮件,发送给多人
- *
- * @param tos 收件人列表
- * @param subject 标题
- * @param content 正文
- * @param files 附件列表
- * @since 3.2.0
- */
- public static void sendHtml(Collection tos, String subject, String content, File... files) {
- send(tos, subject, content, true, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送邮件,发送给多人
- *
- * @param tos 收件人列表
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML
- * @param files 附件列表
- */
- public static void send(Collection tos, String subject, String content, boolean isHtml, File... files) {
- send(tos, null, null, subject, content, isHtml, files);
- }
-
- /**
- * 使用配置文件中设置的账户发送邮件,发送给多人
- *
- * @param tos 收件人列表
- * @param ccs 抄送人列表,可以为null或空
- * @param bccs 密送人列表,可以为null或空
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML
- * @param files 附件列表
- * @since 4.0.3
- */
- public static void send(Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
- send(GlobalMailAccount.INSTANCE.getAccount(), true, tos, ccs, bccs, subject, content, isHtml, files);
- }
-
- //------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
- /**
- * 发送邮件给多人
- *
- * @param mailAccount 邮件认证对象
- * @param to 收件人,多个收件人逗号或者分号隔开
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML格式
- * @param files 附件列表
- * @since 3.2.0
- */
- public static void send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
- send(mailAccount, splitAddress(to), subject, content, isHtml, files);
- }
-
- /**
- * 发送邮件给多人
- *
- * @param mailAccount 邮件帐户信息
- * @param tos 收件人列表
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML格式
- * @param files 附件列表
- */
- public static void send(MailAccount mailAccount, Collection tos, String subject, String content, boolean isHtml, File... files) {
- send(mailAccount, tos, null, null, subject, content, isHtml, files);
- }
-
- /**
- * 发送邮件给多人
- *
- * @param mailAccount 邮件帐户信息
- * @param tos 收件人列表
- * @param ccs 抄送人列表,可以为null或空
- * @param bccs 密送人列表,可以为null或空
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML格式
- * @param files 附件列表
- * @since 4.0.3
- */
- public static void send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
- send(mailAccount, false, tos, ccs, bccs, subject, content, isHtml, files);
- }
-
- //------------------------------------------------------------------------------------------------------------------------ Private method start
- /**
- * 发送邮件给多人
- *
- * @param mailAccount 邮件帐户信息
- * @param useGlobalSession 是否全局共享Session
- * @param tos 收件人列表
- * @param ccs 抄送人列表,可以为null或空
- * @param bccs 密送人列表,可以为null或空
- * @param subject 标题
- * @param content 正文
- * @param isHtml 是否为HTML格式
- * @param files 附件列表
- * @since 4.0.3
- */
- private static void send(MailAccount mailAccount, boolean useGlobalSession, Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
- final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
-
- //可选抄送人
- if(CollUtil.isNotEmpty(ccs)) {
- mail.setCcs(ccs.toArray(new String[ccs.size()]));
- }
- //可选密送人
- if(CollUtil.isNotEmpty(bccs)) {
- mail.setBccs(bccs.toArray(new String[bccs.size()]));
- }
-
- mail.setTos(tos.toArray(new String[tos.size()]));
- mail.setTitle(subject);
- mail.setContent(content);
- mail.setHtml(isHtml);
- mail.setFiles(files);
-
- mail.send();
- }
-
- /**
- * 将多个联系人转为列表,分隔符为逗号或者分号
- *
- * @param addresses 多个联系人,如果为空返回null
- * @return 联系人列表
- */
- private static List splitAddress(String addresses){
- if(StrUtil.isBlank(addresses)) {
- return null;
- }
-
- List result;
- if(StrUtil.contains(addresses, ',')) {
- result = StrUtil.splitTrim(addresses, ',');
- }else if(StrUtil.contains(addresses, ';')) {
- result = StrUtil.splitTrim(addresses, ';');
- }else {
- result = CollUtil.newArrayList(addresses);
- }
- return result;
- }
- //------------------------------------------------------------------------------------------------------------------------ Private method end
-}
+package cn.hutool.extra.mail;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 邮件工具类,基于javax.mail封装
+ *
+ * @author looly
+ * @since 3.1.2
+ */
+public class MailUtil {
+ /**
+ * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void sendText(String to, String subject, String content, File... files) {
+ send(to, subject, content, false, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void sendHtml(String to, String subject, String content, File... files) {
+ send(to, subject, content, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ */
+ public static void send(String to, String subject, String content, boolean isHtml, File... files) {
+ send(splitAddress(to), subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
+ send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送文本邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ */
+ public static void sendText(Collection tos, String subject, String content, File... files) {
+ send(tos, subject, content, false, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void sendHtml(Collection tos, String subject, String content, File... files) {
+ send(tos, subject, content, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ */
+ public static void send(Collection tos, String subject, String content, boolean isHtml, File... files) {
+ send(tos, null, null, subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
+ send(GlobalMailAccount.INSTANCE.getAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files);
+ }
+
+ //------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件认证对象
+ * @param to 收件人,多个收件人逗号或者分号隔开
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
+ send(mailAccount, splitAddress(to), subject, content, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ */
+ public static void send(MailAccount mailAccount, Collection tos, String subject, String content, boolean isHtml, File... files) {
+ send(mailAccount, tos, null, null, subject, content, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
+ send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @since 3.2.0
+ */
+ public static void sendHtml(String to, String subject, String content, Map imageMap, File... files) {
+ send(to, subject, content, imageMap, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ */
+ public static void send(String to, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(splitAddress(to), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(String to, String cc, String bcc, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void sendHtml(Collection tos, String subject, String content, Map imageMap, File... files) {
+ send(tos, subject, content, imageMap, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ */
+ public static void send(Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(tos, null, null, subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(GlobalMailAccount.INSTANCE.getAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+ }
+
+ //------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件认证对象
+ * @param to 收件人,多个收件人逗号或者分号隔开
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @since 3.2.0
+ */
+ public static void send(MailAccount mailAccount, String to, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ */
+ public static void send(MailAccount mailAccount, Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ public static void send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+ }
+
+ //------------------------------------------------------------------------------------------------------------------------ Private method start
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param useGlobalSession 是否全局共享Session
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @since 4.0.3
+ */
+ private static void send(MailAccount mailAccount, boolean useGlobalSession, Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
+
+ //可选抄送人
+ if(CollUtil.isNotEmpty(ccs)) {
+ mail.setCcs(ccs.toArray(new String[ccs.size()]));
+ }
+ //可选密送人
+ if(CollUtil.isNotEmpty(bccs)) {
+ mail.setBccs(bccs.toArray(new String[bccs.size()]));
+ }
+
+ mail.setTos(tos.toArray(new String[tos.size()]));
+ mail.setTitle(subject);
+ mail.setContent(content);
+ mail.setHtml(isHtml);
+ mail.setFiles(files);
+ mail.setImageMap(imageMap);
+
+ mail.send();
+ }
+
+ /**
+ * 将多个联系人转为列表,分隔符为逗号或者分号
+ *
+ * @param addresses 多个联系人,如果为空返回null
+ * @return 联系人列表
+ */
+ private static List splitAddress(String addresses){
+ if(StrUtil.isBlank(addresses)) {
+ return null;
+ }
+
+ List result;
+ if(StrUtil.contains(addresses, ',')) {
+ result = StrUtil.splitTrim(addresses, ',');
+ }else if(StrUtil.contains(addresses, ';')) {
+ result = StrUtil.splitTrim(addresses, ';');
+ }else {
+ result = CollUtil.newArrayList(addresses);
+ }
+ return result;
+ }
+ //------------------------------------------------------------------------------------------------------------------------ Private method end
+}