開篇語,是不是感覺這個功能都老掉牙了,網上一大推的文章,隨便找個代碼就是了,為什么我還要選擇專門寫一篇呢,因為我遇到了不一樣的坑……
首先,不免俗套的把代碼都貼上來,拿去執行吧,記住換上你的賬號和授權密碼,還有收件人郵箱。若是執行成功,不謝,后面不用看了,執行不成功再來看看后面的說的啥吧。
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 = "yu@163.com"; // 該密碼不是登陸密碼,而是授權密碼 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("yu@qq.com", "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 測試!
媽的,頓時醒悟啊,公司的網絡有限制啊!大環境需要翻牆,小環境還需要自己開數據啊!果然,代碼未動,一次通過,心中那個萬千草泥馬啊……
你以為到這里就結束了嘛,並沒有!我回到家,心想這次可以美滋滋的測試我的功能了,結果,出現了這個
嗯,有進步啊,終於有報錯信息了,跟着鏈接去 see 了一 see ,554 錯誤對應着什么,操作頻繁之類的提醒,這次學乖了,我先去 ipconfig 看了一下自己的 IP ,在局域網內嘛,192.168.100.108 嗯,這個 IP 可能是用的人太多了,於是我又用手機數據測試一波,一次通過!爽
然而,事情沒有那么簡單,我連上手機的數據之后發現網絡不過是網段不一樣而已,變成了 192.168.43.249 。我自認為沒什么差別啊,搞不清楚…… 后面我又連上無線,看了一眼 IP 地址還是 192.168.100.108,一執行,終於出現了這個大多數人說的返回 -1 的 bug , 納尼,我貌似還有點開心……
但是經過網絡洗禮的我,怎么可能再次跌倒,管你三七二十一,再強行執行一波,果然,郵件發送成功 !
所以,你和誰說理去呢,就這個功能而言,本地環境這是真的不穩定啊,我看到好多同學說我代碼一點都沒動啊,為什么前幾天還能執行,現在執行不了啊之類的。這真的挺讓你難過的…… 要我說,基本面不出問題,那就是網絡的原因了,請把目光放到網絡上,而不只是代碼上,OK ?
后記:這么看,同一個 IP 一會可以發出去,一會發不出去,我表示很不理解,遂心想,是不是網易對 IP 有限制呀,我咨詢了一下客服,得到的結果是和 IP 沒有關系,和賬號有關,具體解釋是一個賬號每天允許發送 200-400 條。根據你的賬號 level 來定。
可能客服沒有騙我,確實和 IP 沒有關系,那為什么我這一個 IP 一會可用一會不可用呢,我估計是因為我在局域網中吧,因為我的內網地址是 168.192.100.108 .這只是一個內網地址嘛,映射到外網不穩定也是有可能的,若是把這個功能放到自己的服務器上可能就會穩定一些。
全文完。