說實話騰訊的企業郵箱真心不錯!
騰訊企業郵箱官網:http://exmail.qq.com/login/
新用戶注冊:http://exmail.qq.com/onlinesell/intro
點擊開通
你跟着步驟走就行了,沒啥難的,如果你沒有域名,你就去買一個唄,也花不了多少錢的。
注冊成功后,是這個頁面,並且會有一個彈窗告訴你一些信息
現在你點擊添加成員,因為你不添加成員的話你是無法發送郵件的。
完成后是這樣
然后你打開騰訊企業郵箱登錄界面,輸入你剛才增加的成員郵箱的:登錄名 + 密碼,進去后是一個類似於普通QQ郵箱的界面
到這里郵箱部分就解決了,哦還有,騰訊會自動給你發一個郵件,
點開后是這個,
以前寫過普通QQ郵箱的發送代碼,我從沒見過SSL,所以一開始全然不懂。。,但是上網查閱得知
隨着各個Mail服務器對於安全的重視,紛紛采用基於SSL的Mail登陸方式進行發送和接收電子郵件
好了現在開始寫代碼。
大家反映之前寫的容易誤導人,所以今天修改了這個文章一下2017-09-05
有一個屬性文件用來存儲郵箱信息的
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更新:https://www.cnblogs.com/LUA123/p/11265995.html
小伙伴們在使用過程中遇到各種各樣的問題,在下一一列舉。
=============================================================================================
錯誤1:
關於客戶端專用密碼 。
如果說您綁定了微信,就不能繼續使用登錄密碼了,取代的是“客戶端專用密碼”
這里借用一下熱心網友的截圖,以下是綁定微信后的安全設置:登錄方式和專用密碼。
如果你開啟了這些東西,那么在使用Javamail的時候,密碼就要用生成的“專用密碼”
關於“授權碼”
我想說:“不存在的”,如果你用的是企業郵,那么就不需要這個東西吧,你用個人的才需要(純屬猜測,本人也沒用過)
關於發信量
有的小伙伴跟我說發了一定數量就不行了,我特地去查了查,原來這里是個坑(對於頻繁發送的場景十分不利),截圖如下:
所以,我建議想要無限頻繁發送,那就去別的提供商看看,或者自己搭建郵件服務器