絕對良心的 Java 中發郵件功能
開篇語,是不是感覺這個功能都老掉牙了,網上一大推的文章,隨便找個程式碼就是了,為什麼我還要選擇專門寫一篇呢,因為我遇到了不一樣的坑……
首先,不免俗套的把程式碼都貼上來,拿去執行吧,記住換上你的賬號和密碼,還有收件人郵箱。若是執行成功,不謝,後面不用看了,執行不成功再來看看後面的說的啥吧。
package mail; import java.util.Date; import java.util.Properties; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage.RecipientType; import org.junit.Test; public class MailTest { public static final String SMTPSERVER = "smtp.163.com"; public static final String SMTPPORT = "465"; public static final String ACCOUT = "[email protected]"; // 該密碼不是登陸密碼,而是授權密碼 public static final String PWD = "123456"; @Test public void testSendEmail() throws Exception { Properties props = getMailProperties(); // 根據郵件配置建立會話,注意session別導錯包 Session session = Session.getDefaultInstance(props); // 開啟debug模式,可以看到更多詳細的輸入日誌 session.setDebug(true); //建立郵件 MimeMessage message = createEmail(session); //獲取傳輸通道 Transport transport = session.getTransport(); // 連線傳輸通道 transport.connect(SMTPSERVER,ACCOUT, PWD); //傳送郵件 transport.sendMessage(message, message.getAllRecipients()); transport.close(); } /** * 設定郵件相關配置 */ private Properties getMailProperties() { // 建立郵件配置 Properties props = new Properties(); // 使用的協議(JavaMail規範要求) props.setProperty("mail.transport.protocol", "smtp"); // 發件人的郵箱的 SMTP 伺服器地址 props.setProperty("mail.smtp.host", SMTPSERVER); // SMTP 伺服器埠號,預設的埠號為 25 ,因為使用 SSL 連線方式,所以埠號為 465 // 為什麼使用 SSL,傳輸加密,更安全 props.setProperty("mail.smtp.port", SMTPPORT); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.ssl.enable", "true"); // 設定需要請求認證 props.setProperty("mail.smtp.auth", "true"); return props; } /** * 建立郵件 */ public MimeMessage createEmail(Session session) throws Exception { // 根據會話建立郵件 MimeMessage msg = new MimeMessage(session); // address 郵件地址, personal 郵件暱稱, charset 編碼方式 InternetAddress fromAddress = new InternetAddress(ACCOUT,"Dear", "utf-8"); // 設定傳送郵件方 msg.setFrom(fromAddress); InternetAddress receiveAddress = new InternetAddress("[email protected]", "test", "utf-8"); // 設定郵件接收方 msg.setRecipient(RecipientType.TO, receiveAddress); // 設定郵件標題 msg.setSubject("測試標題", "utf-8"); msg.setText("啥都不說,點贊吧!"); // 設定顯示的發件時間 msg.setSentDate(new Date()); // 儲存設定 msg.saveChanges(); return msg; } }
我就是像大多數人一樣,認為這個功能太簡單,網上 copy 一個程式碼,搞定,可惜…… bug 讓我痛不欲生。當我懷著激動的心情執行程式碼的時候,出現了這個
神馬???為什麼連線超時???我能正常訪問網路啊,我連不上 163 的伺服器??是不是網易對我有什麼誤解啊,好吧,翻過百度前幾頁,我找到了這樣的答案,要在 163 郵箱中設定開啟 smtp 的服務,有設定一個授權密碼。操作的頁面在這
這是基本操作好吧,我當然是已經設定好了也再一次驗證了我的授權密碼,然鵝,還是
怎麼辦,我心態有點崩啊,人人都說幾分鐘搞定的事我已經加班幾個小時了,這是為什麼!還是依舊的連線超時,為什麼連不上呢?埠不對?網址不對?一而再再而三的確認了我使用的是 SSL 連線方式所以不能用預設的 SMTP 預設埠 25 ,埠沒毛病啊!對了,我 ping 一下163伺服器,看看行不行唄!一看,沒毛病啊。凌亂了,真想就這樣一直攻擊 163 啊,讓你連線超時。
還會有什麼 bug 呢?再一次打開了百度,整理了這些建議……
1 郵件伺服器的 smtp 服務沒有開啟。 我已經打開了呀! 2 登陸賬號和密碼為賬號和客戶端授權密碼。 我密碼都換了幾個了,就怕記錯! 3 設定認證並開啟 SSL 加密 必須開啟了 4 可能 JDK 的版本過高,安全驗證不通過。 彷彿看到了希望,遂 JDK 由 1.8 變成 1.7 ,bug 依舊…… 5 163,QQ 郵箱伺服器本身頻率和次數有限制。 我這一次都沒成功好吧…… 6 有時候執行成功了,卻不見郵件,請去垃圾箱中找一找……
果不其然,搞了一晚上,還是沒有解決這個難題……
我會輕易放棄嘛,不可能的!第二天繼續搞,這時候忍不住了,不能再強行裝逼了,問了問同事,同事說了一句,用自己的 wifi 測試!
媽的,頓時醒悟啊,公司的網路有限制啊!大環境需要FQ,小環境還需要自己開資料啊!果然,程式碼未動,一次通過,心中那個萬千草泥馬啊……
你以為到這裡就結束了嘛,並沒有!我回到家,心想這次可以美滋滋的測試我的功能了,結果,出現了這個
嗯,有進步啊,終於有報錯資訊了,跟著連結去 see 了一 see ,554 錯誤對應著什麼,操作頻繁之類的提醒,這次學乖了,我先去 ipconfig 看了一下自己的 IP ,在區域網內嘛,192.168.100.108 嗯,這個 IP 可能是用的人太多了,於是我又用手機資料測試一波,一次通過!爽
然而,事情沒有那麼簡單,我連上手機的資料之後發現網路不過是網段不一樣而已,變成了 192.168.43.249 。我自認為沒什麼差別啊,搞不清楚…… 後面我又連上無線,看了一眼 IP 地址還是 192.168.100.108,一執行,報錯了,返回值是 -1 ,沒有想太多,又執行了一次,發現又可以正常傳送了……
所以,你和誰說理去呢,就這個功能而言,這是真的不穩定啊,我還看到好多同學說我程式碼一點都沒動啊,為什麼前幾天還能執行,現在執行不了啊之類的。這真的挺讓你難過的…… 要我說,基本面不出問題,那就是網路的原因了,請把目光放到網路上,而不只是程式碼上,OK ?
全文完。