說實話騰訊的企業郵箱真心不錯!css
騰訊企業郵箱官網:http://exmail.qq.com/login/html
新用戶註冊:http://exmail.qq.com/onlinesell/introjava
點擊開通git
你跟着步驟走就好了,沒啥難的,若是你沒有域名,你就去買一個唄,也花不了多少錢的。github
註冊成功後,是這個頁面,而且會有一個彈窗告訴你一些信息spring
如今你點擊添加成員,由於你不添加成員的話你是沒法發送郵件的。安全
完成後是這樣服務器
而後你打開騰訊企業郵箱登陸界面,輸入你剛纔增長的成員郵箱的:登陸名 + 密碼,進去後是一個相似於普通QQ郵箱的界面微信
到這裏郵箱部分就解決了,哦還有,騰訊會自動給你發一個郵件,session
點開後是這個,
之前寫過普通QQ郵箱的發送代碼,我從沒見過SSL,因此一開始全然不懂。。,可是上網查閱得知
隨着各個Mail服務器對於安全的重視,紛紛採用基於SSL的Mail登錄方式進行發送和接收電子郵件
好了如今開始寫代碼。
有一個屬性文件用來存儲郵箱信息的
email.properties,放在src路徑下面
e.account=帳戶名 e.pass=密碼 e.host=smtp.exmail.qq.com e.port=465 e.protocol=smtp
下面是發送類:
package mail.demo; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.util.Date; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.springframework.core.io.support.PropertiesLoaderUtils; import com.sun.mail.util.MailSSLSocketFactory; public class SendEmailUtil { private static String account; //登陸用戶名 private static String pass; //登陸密碼 private static String host; //服務器地址(郵件服務器) private static String port; //端口 private static String protocol; //協議 static{ Properties prop = new Properties(); // InputStream instream = ClassLoader.getSystemResourceAsStream("email.properties");//測試環境 try { // prop.load(instream);//測試環境 prop = PropertiesLoaderUtils.loadAllProperties("email.properties");//生產環境 } catch (IOException e) { System.out.println("加載屬性文件失敗"); } account = prop.getProperty("e.account"); pass = prop.getProperty("e.pass"); host = prop.getProperty("e.host"); port = prop.getProperty("e.port"); protocol = prop.getProperty("e.protocol"); } static class MyAuthenricator extends Authenticator{ String u = null; String p = null; public MyAuthenricator(String u,String p){ this.u=u; this.p=p; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(u,p); } } private String to; //收件人 private String subject; //主題 private String content; //內容 private String fileStr; //附件路徑 public SendEmailUtil(String to, String subject, String content, String fileStr) { this.to = to; this.subject = subject; this.content = content; this.fileStr = fileStr; } public void send(){ Properties prop = new Properties(); //協議 prop.setProperty("mail.transport.protocol", protocol); //服務器 prop.setProperty("mail.smtp.host", host); //端口 prop.setProperty("mail.smtp.port", port); //使用smtp身份驗證 prop.setProperty("mail.smtp.auth", "true"); //使用SSL,企業郵箱必需! //開啓安全協議 MailSSLSocketFactory sf = null; try { sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); } catch (GeneralSecurityException e1) { e1.printStackTrace(); } prop.put("mail.smtp.ssl.enable", "true"); prop.put("mail.smtp.ssl.socketFactory", sf); Session session = Session.getDefaultInstance(prop, new MyAuthenricator(account, pass)); session.setDebug(true); MimeMessage mimeMessage = new MimeMessage(session); try { //發件人 mimeMessage.setFrom(new InternetAddress(account,"XXX")); //能夠設置發件人的別名 //mimeMessage.setFrom(new InternetAddress(account)); //若是不須要就省略 //收件人 mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); //主題 mimeMessage.setSubject(subject); //時間 mimeMessage.setSentDate(new Date()); //容器類,能夠包含多個MimeBodyPart對象 Multipart mp = new MimeMultipart(); //MimeBodyPart能夠包裝文本,圖片,附件 MimeBodyPart body = new MimeBodyPart(); //HTML正文 body.setContent(content, "text/html; charset=UTF-8"); mp.addBodyPart(body); //添加圖片&附件 body = new MimeBodyPart(); body.attachFile(fileStr); mp.addBodyPart(body); //設置郵件內容 mimeMessage.setContent(mp); //僅僅發送文本 //mimeMessage.setText(content); mimeMessage.saveChanges(); Transport.send(mimeMessage); } catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
考慮到實際中要保證吞吐量,我寫了一個線程:
package mail.demo; public class Sending implements Runnable{ private String to; //收件人 private String subject; //主題 private String content; //內容 private String fileStr; //附件路徑 public Sending(String to, String subject, String content, String fileStr) { this.to = to; this.subject = subject; this.content = content; this.fileStr = fileStr; } @Override public void run() { SendEmailUtil sendEmail = new SendEmailUtil(to, subject, content, fileStr); sendEmail.send(); } }
線程的創建銷燬開銷也是很大的,我建了一個線程池,若是遇到批量處理的話能夠好用一些。
package mail.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 單例,線程池 * @author Taozi * */ public class SendingPool { private SendingPool() { } private static class Inner{ private static SendingPool instance = new SendingPool(); } public static SendingPool getInstance(){ return Inner.instance; } private static int nThreads = 10; private static ExecutorService executor = Executors.newFixedThreadPool(nThreads); public SendingPool addThread(Sending sending){ executor.execute(sending); return getInstance(); } public void shutDown(){ executor.shutdown(); } }
下面是測試類
package mail.demo; public class MyTest { public static void main(String[] args) { SendingPool pool = SendingPool.getInstance(); pool.addThread(new Sending("收件人", "AAA", createEmail().toString(), "file/1.jpg")).shutDown(); } private static StringBuilder createEmail() { StringBuilder emailContent = new StringBuilder("<!DOCTYPE html><html><head><meta charset='UTF-8'><title>快來買桃子</title><style type='text/css'> .container{ font-family: 'Microsoft YaHei'; width: 600px; margin: 0 auto; padding: 8px; border: 3px dashed #db303f; border-radius: 6px; } .title{ text-align: center; color: #db303f; } .content{ text-align: justify; color: #717273; font-weight: 600; } footer{ text-align: right; color: #db303f; font-weight: 600; font-size: 18px; }</style></head><body><div class='container'><h2 class='title'>好吃的桃子</h2><p class='content'>桃子含有維生素A、維生素B和維生素C,兒童多吃桃子可以使身體健康成長,由於桃子含有的多種維生索能夠直接強化他們的身體和智力。</p><footer>聯繫桃子:11110000</footer></div></body></html>"); return emailContent; } }
提示:實際中不要調用shutDown方法,由於這個是優雅關閉線程池的,若是你關閉了再次調用是會出問題的喲
提示2:若是你不須要附件的功能,請把附件相關的代碼註釋,或者加個判斷
//添加圖片&附件 if(fileStr != null){ body = new MimeBodyPart(); body.attachFile(fileStr); mp.addBodyPart(body); }
下面是我收到的郵件,Html正文+附件
到此就完成了
完整代碼去GitHub下載,Javamail
2019-07-29更新:http://www.javashuo.com/article/p-yjchpxsp-gx.html
小夥伴們在使用過程當中遇到各類各樣的問題,在下一一列舉。
=============================================================================================
關於客戶端專用密碼 。
若是說您綁定了微信,就不能繼續使用登陸密碼了,取代的是「客戶端專用密碼」
這裏借用一下熱心網友的截圖,如下是綁定微信後的安全設置:登陸方式和專用密碼。
若是你開啓了這些東西,那麼在使用Javamail的時候,密碼就要用生成的「專用密碼」
關於「受權碼」
我想說:「不存在的」,若是你用的是企業郵,那麼就不須要這個東西吧,你用我的的才須要(純屬猜想,本人也沒用過)
有的小夥伴跟我說發了必定數量就不行了,我特意去查了查,原來這裏是個坑(對於頻繁發送的場景十分不利),截圖以下:
因此,我建議想要無限頻繁發送,那就去別的提供商看看,或者本身搭建郵件服務器