MailUtils.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. package com.ruoyi.common.utils.email;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.io.IoUtil;
  4. import cn.hutool.core.map.MapUtil;
  5. import cn.hutool.core.util.CharUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import cn.hutool.extra.mail.*;
  8. import com.ruoyi.common.utils.StringUtils;
  9. import com.ruoyi.common.utils.spring.SpringUtils;
  10. import lombok.AccessLevel;
  11. import lombok.NoArgsConstructor;
  12. import javax.mail.Authenticator;
  13. import javax.mail.Session;
  14. import java.io.File;
  15. import java.io.InputStream;
  16. import java.util.Collection;
  17. import java.util.List;
  18. import java.util.Map;
  19. /**
  20. * 邮件工具类
  21. */
  22. @NoArgsConstructor(access = AccessLevel.PRIVATE)
  23. public class MailUtils {
  24. private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class);
  25. /**
  26. * 获取邮件发送实例
  27. */
  28. public static MailAccount getMailAccount() {
  29. return ACCOUNT;
  30. }
  31. /**
  32. * 获取邮件发送实例 (自定义发送人以及授权码)
  33. *
  34. * @param user 发送人
  35. * @param pass 授权码
  36. */
  37. public static MailAccount getMailAccount(String from, String user, String pass) {
  38. ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom()));
  39. ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser()));
  40. ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass()));
  41. return ACCOUNT;
  42. }
  43. /**
  44. * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人<br>
  45. * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  46. *
  47. * @param to 收件人
  48. * @param subject 标题
  49. * @param content 正文
  50. * @param files 附件列表
  51. * @return message-id
  52. * @since 3.2.0
  53. */
  54. public static String sendText(String to, String subject, String content, File... files) {
  55. return send(to, subject, content, false, files);
  56. }
  57. /**
  58. * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人<br>
  59. * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  60. *
  61. * @param to 收件人
  62. * @param subject 标题
  63. * @param content 正文
  64. * @param files 附件列表
  65. * @return message-id
  66. * @since 3.2.0
  67. */
  68. public static String sendHtml(String to, String subject, String content, File... files) {
  69. return send(to, subject, content, true, files);
  70. }
  71. /**
  72. * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人<br>
  73. * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  74. *
  75. * @param to 收件人
  76. * @param subject 标题
  77. * @param content 正文
  78. * @param isHtml 是否为HTML
  79. * @param files 附件列表
  80. * @return message-id
  81. */
  82. public static String send(String to, String subject, String content, boolean isHtml, File... files) {
  83. return send(splitAddress(to), subject, content, isHtml, files);
  84. }
  85. /**
  86. * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人<br>
  87. * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  88. *
  89. * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  90. * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  91. * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  92. * @param subject 标题
  93. * @param content 正文
  94. * @param isHtml 是否为HTML
  95. * @param files 附件列表
  96. * @return message-id
  97. * @since 4.0.3
  98. */
  99. public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
  100. return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
  101. }
  102. /**
  103. * 使用配置文件中设置的账户发送文本邮件,发送给多人
  104. *
  105. * @param tos 收件人列表
  106. * @param subject 标题
  107. * @param content 正文
  108. * @param files 附件列表
  109. * @return message-id
  110. */
  111. public static String sendText(Collection<String> tos, String subject, String content, File... files) {
  112. return send(tos, subject, content, false, files);
  113. }
  114. /**
  115. * 使用配置文件中设置的账户发送HTML邮件,发送给多人
  116. *
  117. * @param tos 收件人列表
  118. * @param subject 标题
  119. * @param content 正文
  120. * @param files 附件列表
  121. * @return message-id
  122. * @since 3.2.0
  123. */
  124. public static String sendHtml(Collection<String> tos, String subject, String content, File... files) {
  125. return send(tos, subject, content, true, files);
  126. }
  127. /**
  128. * 使用配置文件中设置的账户发送邮件,发送给多人
  129. *
  130. * @param tos 收件人列表
  131. * @param subject 标题
  132. * @param content 正文
  133. * @param isHtml 是否为HTML
  134. * @param files 附件列表
  135. * @return message-id
  136. */
  137. public static String send(Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
  138. return send(tos, null, null, subject, content, isHtml, files);
  139. }
  140. /**
  141. * 使用配置文件中设置的账户发送邮件,发送给多人
  142. *
  143. * @param tos 收件人列表
  144. * @param ccs 抄送人列表,可以为null或空
  145. * @param bccs 密送人列表,可以为null或空
  146. * @param subject 标题
  147. * @param content 正文
  148. * @param isHtml 是否为HTML
  149. * @param files 附件列表
  150. * @return message-id
  151. * @since 4.0.3
  152. */
  153. public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
  154. return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files);
  155. }
  156. // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
  157. /**
  158. * 发送邮件给多人
  159. *
  160. * @param mailAccount 邮件认证对象
  161. * @param to 收件人,多个收件人逗号或者分号隔开
  162. * @param subject 标题
  163. * @param content 正文
  164. * @param isHtml 是否为HTML格式
  165. * @param files 附件列表
  166. * @return message-id
  167. * @since 3.2.0
  168. */
  169. public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
  170. return send(mailAccount, splitAddress(to), subject, content, isHtml, files);
  171. }
  172. /**
  173. * 发送邮件给多人
  174. *
  175. * @param mailAccount 邮件帐户信息
  176. * @param tos 收件人列表
  177. * @param subject 标题
  178. * @param content 正文
  179. * @param isHtml 是否为HTML格式
  180. * @param files 附件列表
  181. * @return message-id
  182. */
  183. public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
  184. return send(mailAccount, tos, null, null, subject, content, isHtml, files);
  185. }
  186. /**
  187. * 发送邮件给多人
  188. *
  189. * @param mailAccount 邮件帐户信息
  190. * @param tos 收件人列表
  191. * @param ccs 抄送人列表,可以为null或空
  192. * @param bccs 密送人列表,可以为null或空
  193. * @param subject 标题
  194. * @param content 正文
  195. * @param isHtml 是否为HTML格式
  196. * @param files 附件列表
  197. * @return message-id
  198. * @since 4.0.3
  199. */
  200. public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
  201. return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files);
  202. }
  203. /**
  204. * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人<br>
  205. * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  206. *
  207. * @param to 收件人
  208. * @param subject 标题
  209. * @param content 正文
  210. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  211. * @param files 附件列表
  212. * @return message-id
  213. * @since 3.2.0
  214. */
  215. public static String sendHtml(String to, String subject, String content, Map<String, InputStream> imageMap, File... files) {
  216. return send(to, subject, content, imageMap, true, files);
  217. }
  218. /**
  219. * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人<br>
  220. * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  221. *
  222. * @param to 收件人
  223. * @param subject 标题
  224. * @param content 正文
  225. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  226. * @param isHtml 是否为HTML
  227. * @param files 附件列表
  228. * @return message-id
  229. */
  230. public static String send(String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  231. return send(splitAddress(to), subject, content, imageMap, isHtml, files);
  232. }
  233. /**
  234. * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人<br>
  235. * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
  236. *
  237. * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  238. * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  239. * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
  240. * @param subject 标题
  241. * @param content 正文
  242. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  243. * @param isHtml 是否为HTML
  244. * @param files 附件列表
  245. * @return message-id
  246. * @since 4.0.3
  247. */
  248. public static String send(String to, String cc, String bcc, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  249. return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files);
  250. }
  251. /**
  252. * 使用配置文件中设置的账户发送HTML邮件,发送给多人
  253. *
  254. * @param tos 收件人列表
  255. * @param subject 标题
  256. * @param content 正文
  257. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  258. * @param files 附件列表
  259. * @return message-id
  260. * @since 3.2.0
  261. */
  262. public static String sendHtml(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, File... files) {
  263. return send(tos, subject, content, imageMap, true, files);
  264. }
  265. /**
  266. * 使用配置文件中设置的账户发送邮件,发送给多人
  267. *
  268. * @param tos 收件人列表
  269. * @param subject 标题
  270. * @param content 正文
  271. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  272. * @param isHtml 是否为HTML
  273. * @param files 附件列表
  274. * @return message-id
  275. */
  276. public static String send(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  277. return send(tos, null, null, subject, content, imageMap, isHtml, files);
  278. }
  279. /**
  280. * 使用配置文件中设置的账户发送邮件,发送给多人
  281. *
  282. * @param tos 收件人列表
  283. * @param ccs 抄送人列表,可以为null或空
  284. * @param bccs 密送人列表,可以为null或空
  285. * @param subject 标题
  286. * @param content 正文
  287. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  288. * @param isHtml 是否为HTML
  289. * @param files 附件列表
  290. * @return message-id
  291. * @since 4.0.3
  292. */
  293. public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  294. return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
  295. }
  296. // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
  297. /**
  298. * 发送邮件给多人
  299. *
  300. * @param mailAccount 邮件认证对象
  301. * @param to 收件人,多个收件人逗号或者分号隔开
  302. * @param subject 标题
  303. * @param content 正文
  304. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  305. * @param isHtml 是否为HTML格式
  306. * @param files 附件列表
  307. * @return message-id
  308. * @since 3.2.0
  309. */
  310. public static String send(MailAccount mailAccount, String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  311. return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files);
  312. }
  313. /**
  314. * 发送邮件给多人
  315. *
  316. * @param mailAccount 邮件帐户信息
  317. * @param tos 收件人列表
  318. * @param subject 标题
  319. * @param content 正文
  320. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  321. * @param isHtml 是否为HTML格式
  322. * @param files 附件列表
  323. * @return message-id
  324. * @since 4.6.3
  325. */
  326. public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  327. return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files);
  328. }
  329. /**
  330. * 发送邮件给多人
  331. *
  332. * @param mailAccount 邮件帐户信息
  333. * @param tos 收件人列表
  334. * @param ccs 抄送人列表,可以为null或空
  335. * @param bccs 密送人列表,可以为null或空
  336. * @param subject 标题
  337. * @param content 正文
  338. * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
  339. * @param isHtml 是否为HTML格式
  340. * @param files 附件列表
  341. * @return message-id
  342. * @since 4.6.3
  343. */
  344. public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap,
  345. boolean isHtml, File... files) {
  346. return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
  347. }
  348. /**
  349. * 根据配置文件,获取邮件客户端会话
  350. *
  351. * @param mailAccount 邮件账户配置
  352. * @param isSingleton 是否单例(全局共享会话)
  353. * @return {@link Session}
  354. * @since 5.5.7
  355. */
  356. public static Session getSession(MailAccount mailAccount, boolean isSingleton) {
  357. Authenticator authenticator = null;
  358. if (mailAccount.isAuth()) {
  359. authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
  360. }
  361. return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
  362. : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
  363. }
  364. // ------------------------------------------------------------------------------------------------------------------------ Private method start
  365. /**
  366. * 发送邮件给多人
  367. *
  368. * @param mailAccount 邮件帐户信息
  369. * @param useGlobalSession 是否全局共享Session
  370. * @param tos 收件人列表
  371. * @param ccs 抄送人列表,可以为null或空
  372. * @param bccs 密送人列表,可以为null或空
  373. * @param subject 标题
  374. * @param content 正文
  375. * @param imageMap 图片与占位符,占位符格式为cid:${cid}
  376. * @param isHtml 是否为HTML格式
  377. * @param files 附件列表
  378. * @return message-id
  379. * @since 4.6.3
  380. */
  381. private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content,
  382. Map<String, InputStream> imageMap, boolean isHtml, File... files) {
  383. final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
  384. // 可选抄送人
  385. if (CollUtil.isNotEmpty(ccs)) {
  386. mail.setCcs(ccs.toArray(new String[0]));
  387. }
  388. // 可选密送人
  389. if (CollUtil.isNotEmpty(bccs)) {
  390. mail.setBccs(bccs.toArray(new String[0]));
  391. }
  392. mail.setTos(tos.toArray(new String[0]));
  393. mail.setTitle(subject);
  394. mail.setContent(content);
  395. mail.setHtml(isHtml);
  396. mail.setFiles(files);
  397. // 图片
  398. if (MapUtil.isNotEmpty(imageMap)) {
  399. for (Map.Entry<String, InputStream> entry : imageMap.entrySet()) {
  400. mail.addImage(entry.getKey(), entry.getValue());
  401. // 关闭流
  402. IoUtil.close(entry.getValue());
  403. }
  404. }
  405. return mail.send();
  406. }
  407. /**
  408. * 将多个联系人转为列表,分隔符为逗号或者分号
  409. *
  410. * @param addresses 多个联系人,如果为空返回null
  411. * @return 联系人列表
  412. */
  413. private static List<String> splitAddress(String addresses) {
  414. if (StrUtil.isBlank(addresses)) {
  415. return null;
  416. }
  417. List<String> result;
  418. if (StrUtil.contains(addresses, CharUtil.COMMA)) {
  419. result = StrUtil.splitTrim(addresses, CharUtil.COMMA);
  420. } else if (StrUtil.contains(addresses, ';')) {
  421. result = StrUtil.splitTrim(addresses, ';');
  422. } else {
  423. result = CollUtil.newArrayList(addresses);
  424. }
  425. return result;
  426. }
  427. // ------------------------------------------------------------------------------------------------------------------------ Private method end
  428. }