1 import lombok.extern.slf4j.Slf4j; 2 import org.apache.commons.lang3.StringUtils; 3 4 import javax.activation.DataHandler; 5 import javax.activation.FileDataSource; 6 import javax.mail.Address; 7 import javax.mail.Message; 8 import javax.mail.Session; 9 import javax.mail.Transport; 10 import javax.mail.internet.*; 11 import java.util.Date; 12 import java.util.Properties; 13 14 /** 15 * @author <a herf="mailto:yanwu0527@163.com">yanwu</a> 16 * @date 2019-10-22 14:17. 17 * <p> 18 * description: 邮件工具类 19 */ 20 @Slf4j 21 public class EmailUtil { 22 /*** 发件人地址 */ 23 private static final String SEND_ADDRESS = "xxxxxxx@qq.com"; 24 /*** 发件人账户名 */ 25 private static final String ACCOUNT = "xxxxxxx@qq.com"; 26 /*** 发件人账户密码[注:此密码不是邮箱登陆密码,而是邮箱授权密码] */ 27 private static final String PASSWORD = "xxxxxxx"; 28 29 private static final String UTF_8 = "UTF-8"; 30 private static final String CONTENT_TYPE = "text/html;charset=UTF-8"; 31 32 /*** 连接邮件服务器的参数配置 */ 33 private static final Properties PROPERTIES; 34 35 static { 36 PROPERTIES = new Properties(); 37 // ----- 设置用户的认证方式 38 PROPERTIES.setProperty("mail.smtp.auth", "true"); 39 // ----- 设置传输协议 40 PROPERTIES.setProperty("mail.transport.protocol", "smtp"); 41 // ----- 设置发件人的SMTP服务器地址 42 PROPERTIES.setProperty("mail.smtp.host", "smtp.qq.com"); 43 } 44 45 public static void main(String[] args) throws Exception { 46 String toRecipient = "xxx@163.com"; 47 String[] ccRecipient = {"xxx@qq.com", "xxx@qq.com"}; 48 String subject = "测试邮件"; 49 String content = "尊敬的用户:xxx@qq.com,您的车票已经抢票成功!信息如下:乘客:xx,日期:xxxx-xx-xx,车次:xxx,地点:杭州xx:xx-合肥xx:xx,席别:硬座。请在30分钟内完成付款!更多信息请查询未付款订单。"; 50 String[] attachments = {"F:\compression\base_menu.sql", "E:\log\tcp-client.log"}; 51 sendEmail(toRecipient, ccRecipient, subject, content, attachments); 52 } 53 54 /** 55 * 发送邮件[使用默认的发件人信息] 56 * 57 * @param toRecipient 接收人地址 58 * @param ccRecipient 抄送人地址 [为null则不抄送] 59 * @param subject 主题 60 * @param content 内容 61 * @param attachments 附件 [为null则表示无附件] 62 * @throws Exception 63 */ 64 public static void sendEmail(String toRecipient, String[] ccRecipient, 65 String subject, String content, String... attachments) throws Exception { 66 sendEmail(SEND_ADDRESS, ACCOUNT, PASSWORD, toRecipient, ccRecipient, subject, content, attachments); 67 } 68 69 /** 70 * 发送邮件[使用指定的发件人信息] 71 * 72 * @param sendAddress 发送人地址 73 * @param account 发送人账号 74 * @param password 发送人密码 75 * @param toRecipient 接收人地址 76 * @param ccRecipient 抄送人地址 [为null则不抄送] 77 * @param subject 主题 78 * @param content 内容 79 * @param attachments 附件 [为null则表示无附件] 80 * @throws Exception 81 */ 82 public static void sendEmail(String sendAddress, String account, String password, 83 String toRecipient, String[] ccRecipient, 84 String subject, String content, String... attachments) throws Exception { 85 log.info("发送人: [{}], 接收人: [{}], 抄送人: {}, 主题: [{}], 内容: [{}], 附件: {}", sendAddress, toRecipient, ccRecipient, subject, content, attachments); 86 // ===== 参数校验 87 checkParam(sendAddress, "sender address cannot be empty!"); 88 checkParam(account, "sender account cannot be empty!"); 89 checkParam(password, "sender password cannot be empty!"); 90 checkParam(toRecipient, "recipient address cannot be empty!"); 91 checkParam(subject, "mail subject cannot be empty!"); 92 checkParam(content, "mail content cannot be empty!"); 93 // ===== 创建定义整个应用程序所需的环境信息的 Session 对象 94 Session session = Session.getInstance(PROPERTIES); 95 // ===== 创建邮件的实例对象 96 Message msg = getMimeMessage(session, sendAddress, toRecipient, ccRecipient, subject, content, attachments); 97 // ===== 根据session对象获取邮件传输对象Transport 98 Transport transport = session.getTransport(); 99 // ----- 设置发件人的账户名和密码 100 transport.connect(account, password); 101 // ----- 发送邮件,并发送到所有收件人地址,message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人 102 transport.sendMessage(msg, msg.getAllRecipients()); 103 // ===== 关闭邮件连接 104 transport.close(); 105 } 106 107 /** 108 * 获得创建一封邮件的实例对象 109 * 110 * @param session session 111 * @param sendAddress 发送人地址 112 * @param toRecipient 接收人地址 113 * @param ccRecipient 抄送人地址 114 * @param subject 主题 115 * @param content 内容 116 * @param attachments 附件 117 * @return 邮件的实例对象 118 * @throws Exception 119 */ 120 private static MimeMessage getMimeMessage(Session session, String sendAddress, 121 String toRecipient, String[] ccRecipient, 122 String subject, String content, String... attachments) throws Exception { 123 // ----- 创建一封邮件的实例对象 124 MimeMessage msg = new MimeMessage(session); 125 // ===== 发件人地址 126 msg.setFrom(new InternetAddress(sendAddress)); 127 // ===== 收件人地址 128 msg.setRecipients(MimeMessage.RecipientType.TO, toRecipient); 129 if (ArrayUtil.isNotEmpty(ccRecipient)) { 130 // ----- 抄送人 131 Address[] addresses = new InternetAddress[ccRecipient.length]; 132 for (int i = 0; i < ccRecipient.length; i++) { 133 String cc = ccRecipient[i]; 134 checkParam(cc, "Cc address cannot be empty!"); 135 addresses[i] = new InternetAddress(cc); 136 } 137 msg.setRecipients(MimeMessage.RecipientType.CC, addresses); 138 } 139 // ===== 邮件主题 140 msg.setSubject(subject, UTF_8); 141 // ===== 邮件处理附件 142 if (ArrayUtil.isEmpty(attachments)) { 143 // ----- 邮件正文 144 msg.setContent(content, CONTENT_TYPE); 145 } else { 146 // ----- 附件 147 MimeMultipart mm = new MimeMultipart(); 148 // ----- 邮件正文 149 MimeBodyPart text = new MimeBodyPart(); 150 text.setContent(content, CONTENT_TYPE); 151 mm.addBodyPart(text); 152 // ----- 处理附件 153 for (String path : attachments) { 154 if (StringUtils.isBlank(path)) { 155 continue; 156 } 157 // ===== 创建附件节点 158 MimeBodyPart attachment = new MimeBodyPart(); 159 // ----- 读取本地文件 160 DataHandler dh = new DataHandler(new FileDataSource(path)); 161 // ----- 将附件数据添加到节点 162 attachment.setDataHandler(dh); 163 // ----- 设置附件的文件名(需要编码) 164 attachment.setFileName(MimeUtility.encodeText(dh.getName(), UTF_8, null)); 165 mm.addBodyPart(attachment); 166 } 167 mm.setSubType("mixed"); 168 msg.setContent(mm); 169 } 170 // ----- 设置邮件的发送时间,默认立即发送 171 msg.setSentDate(new Date()); 172 return msg; 173 } 174 175 /** 176 * 参数校验 177 * 178 * @param str 参数 179 * @param msg 异常信息 180 */ 181 private static void checkParam(String str, String msg) { 182 if (StringUtils.isBlank(str)) { 183 throw new RuntimeException(msg); 184 } 185 } 186 }