好了,進入這個系列教程最主要的步驟了,前面郵件的理論知識我們都了解了,那么這篇博客我們將用代碼完成郵件的發(fā)送。這在實際項目中應用的非常廣泛,比如注冊需要發(fā)送郵件進行賬號激活,再比如oa項目中利用郵件進行任務提醒等等。我們這里所講的就是利用 javamail 完成郵件的發(fā)送和接收功能。
ps:本篇博客源碼下載鏈接:https://github.com/ysocean/cnblogs
1、javamail 介紹
javamail 是sun公司(現(xiàn)以被甲骨文收購)為方便java開發(fā)人員在應用程序中實現(xiàn)郵件發(fā)送和接收功能而提供的一套標準開發(fā)包,它支持一些常用的郵件協(xié)議,如前面所講的smtp,pop3,imap,還有mime等。我們在使用javamail api 編寫郵件時,無須考慮郵件的底層實現(xiàn)細節(jié),只要調(diào)用javamail 開發(fā)包中相應的api類就可以了。
javamail 下載地址: https://github.com/javaee/javamail/releases
下載這個版本的javamail,包含了smtp, imap, 和 pop3 協(xié)議的實現(xiàn)。
2、javamail api
javamail api 按照功能可以劃分為如下三大類:
①、創(chuàng)建和解析郵件的api
②、發(fā)送郵件的api
③、接收郵件的api
以上三種類型的api在javamail 中由多個類組成,但是主要有四個核心類,我們在編寫程序時,記住這四個核心類,就很容易編寫出java郵件處理程序。
①、message 類:javax.mail.message 類是創(chuàng)建和解析郵件的核心 api,這是一個抽象類,通常使用它的子類javax.mail.internet.mimemessage 類。它的實例對象表示一份電子郵件。客戶端程序發(fā)送郵件時,首先使用創(chuàng)建郵件的 javamail api 創(chuàng)建出封裝了郵件數(shù)據(jù)的 message 對象,然后把這個對象傳遞給郵件發(fā)送api(transport 類) 發(fā)送。客戶端程序接收郵件時,郵件接收api把接收到的郵件數(shù)據(jù)封裝在message 類的實例中,客戶端程序在使用郵件解析api從這個對象中解析收到的郵件數(shù)據(jù)。
②、transport 類:javax.mail.transport 類是發(fā)送郵件的核心api 類,它的實例對象代表實現(xiàn)了某個郵件發(fā)送協(xié)議的郵件發(fā)送對象,例如 smtp 協(xié)議,客戶端程序創(chuàng)建好 message 對象后,只需要使用郵件發(fā)送api 得到 transport 對象,然后把 message 對象傳遞給 transport 對象,并調(diào)用它的發(fā)送方法,就可以把郵件發(fā)送給指定的 smtp 服務器。
③、store 類:javax.mail.store 類是接收郵件的核心 api 類,它的實例對象代表實現(xiàn)了某個郵件接收協(xié)議的郵件接收對象,例如 pop3 協(xié)議,客戶端程序接收郵件時,只需要使用郵件接收 api 得到 store 對象,然后調(diào)用 store 對象的接收方法,就可以從指定的 pop3 服務器獲得郵件數(shù)據(jù),并把這些郵件數(shù)據(jù)封裝到表示郵件的 message 對象中。
④、session 類:javax.mail.session 類用于定義整個應用程序所需的環(huán)境信息,以及收集客戶端與郵件服務器建立網(wǎng)絡連接的會話信息,例如郵件服務器的主機名、端口號、采用的郵件發(fā)送和接收協(xié)議等。session 對象根據(jù)這些信息構(gòu)建用于郵件收發(fā)的 transport 和 store 對象,以及為客戶端創(chuàng)建 message 對象時提供信息支持。
3、使用 javamail 發(fā)送簡單的純文本郵件
在理解下面通過代碼實現(xiàn)郵件的發(fā)送時,我們可以將郵件發(fā)送假想為火箭運載這衛(wèi)星發(fā)送。其中message 是衛(wèi)星,transport 是火箭,而衛(wèi)星和火箭的構(gòu)建都需要 session 的幫助,這樣的關(guān)系更加便于記憶。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
package com.ys.mail; import java.io.objectinputstream.getfield; import java.util.date; import java.util.properties; import javax.mail.address; import javax.mail.message; import javax.mail.messagingexception; import javax.mail.session; import javax.mail.transport; import javax.mail.internet.addressexception; import javax.mail.internet.internetaddress; import javax.mail.internet.mimemessage; import javax.swing.text.html.minimalhtmlwriter; public class sendmailtext { //發(fā)件人地址 //收件人地址 //發(fā)件人賬戶名 public static string senderaccount = "xxx" ; //發(fā)件人賬戶密碼 public static string senderpassword = "xxx" ; public static void main(string[] args) throws exception { //1、連接郵件服務器的參數(shù)配置 properties props = new properties(); //設(shè)置用戶的認證方式 props.setproperty( "mail.smtp.auth" , "true" ); //設(shè)置傳輸協(xié)議 props.setproperty( "mail.transport.protocol" , "smtp" ); //設(shè)置發(fā)件人的smtp服務器地址 props.setproperty( "mail.smtp.host" , "smtp.163.com" ); //2、創(chuàng)建定義整個應用程序所需的環(huán)境信息的 session 對象 session session = session.getinstance(props); //設(shè)置調(diào)試信息在控制臺打印出來 session.setdebug( true ); //3、創(chuàng)建郵件的實例對象 message msg = getmimemessage(session); //4、根據(jù)session對象獲取郵件傳輸對象transport transport transport = session.gettransport(); //設(shè)置發(fā)件人的賬戶名和密碼 transport.connect(senderaccount, senderpassword); //發(fā)送郵件,并發(fā)送到所有收件人地址,message.getallrecipients() 獲取到的是在創(chuàng)建郵件對象時添加的所有收件人, 抄送人, 密送人 transport.sendmessage(msg,msg.getallrecipients()); //如果只想發(fā)送給指定的人,可以如下寫法 //transport.sendmessage(msg, new address[]{new internetaddress("[email protected]")}); //5、關(guān)閉郵件連接 transport.close(); } /** * 獲得創(chuàng)建一封郵件的實例對象 * @param session * @return * @throws messagingexception * @throws addressexception */ public static mimemessage getmimemessage(session session) throws exception{ //創(chuàng)建一封郵件的實例對象 mimemessage msg = new mimemessage(session); //設(shè)置發(fā)件人地址 msg.setfrom( new internetaddress(senderaddress)); /** * 設(shè)置收件人地址(可以增加多個收件人、抄送、密送),即下面這一行代碼書寫多行 * mimemessage.recipienttype.to:發(fā)送 * mimemessage.recipienttype.cc:抄送 * mimemessage.recipienttype.bcc:密送 */ msg.setrecipient(mimemessage.recipienttype.to, new internetaddress(recipientaddress)); //設(shè)置郵件主題 msg.setsubject( "郵件主題" , "utf-8" ); //設(shè)置郵件正文 msg.setcontent( "簡單的純文本郵件!" , "text/html;charset=utf-8" ); //設(shè)置郵件的發(fā)送時間,默認立即發(fā)送 msg.setsentdate( new date()); return msg; } } |
上述的代碼有詳細的注釋,大家不懂得可以留言。注意:大家自己在運行時請將收件人,發(fā)件人等信息更改成自己的。
執(zhí)行完上述代碼,然后我們查看收件箱:
那么一封簡單的純文本文件就發(fā)送完畢了。
4、郵件發(fā)送問題
①、發(fā)件人的郵箱賬戶名和密碼:有的郵箱設(shè)置了獨立密碼,還有的必須用授權(quán)碼登錄(qq郵箱),這在 這篇博客中有介紹。
②、發(fā)件人的smtp服務器地址:一般是 smtp.xxx.com,比如163郵箱是smtp.163.com,qq郵箱是smtp.qq.com。
③、有可能你收件人地址,發(fā)件人地址等信息都正確了,控制臺也打印了正確的信息,但是在收件箱就是收不到信息。這是因為可能收件箱服務器拒收了你發(fā)的郵件(比如認為你的郵件是廣告),這時候可能在垃圾箱里能找到,可能找不到。解決辦法是重復的郵件內(nèi)容不要多次發(fā)送,或者更換收件箱試試。
④、本實例使用的是javamail1.6版本,支持的jdk必須是jdk1.7版本!!!
5、使用 javamail 接收郵件
由于接收郵件的用處不多,這里我們就簡單的給出一個實例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.ys.mail; import java.util.properties; import javax.mail.address; import javax.mail.folder; import javax.mail.message; import javax.mail.session; import javax.mail.store; public class recipientmail { //收件人地址 //收件人賬戶名 public static string recipientaccount = "xxx" ; //收件人賬戶密碼 public static string recipientpassword = "xxx" ; public static void main(string[] args) throws exception { //1、連接郵件服務器的參數(shù)配置 properties props = new properties(); //設(shè)置傳輸協(xié)議 props.setproperty( "mail.store.protocol" , "pop3" ); //設(shè)置收件人的pop3服務器 props.setproperty( "mail.pop3.host" , "pop3.163.com" ); //2、創(chuàng)建定義整個應用程序所需的環(huán)境信息的 session 對象 session session = session.getinstance(props); //設(shè)置調(diào)試信息在控制臺打印出來 //session.setdebug(true); store store = session.getstore( "pop3" ); //連接收件人pop3服務器 store.connect( "pop3.163.com" , recipientaccount, recipientpassword); //獲得用戶的郵件賬戶,注意通過pop3協(xié)議獲取某個郵件夾的名稱只能為inbox folder folder = store.getfolder( "inbox" ); //設(shè)置對郵件賬戶的訪問權(quán)限 folder.open(folder.read_write); //得到郵件賬戶的所有郵件信息 message [] messages = folder.getmessages(); for ( int i = 0 ; i < messages.length ; i++){ //獲得郵件主題 string subject = messages[i].getsubject(); //獲得郵件發(fā)件人 address[] from = messages[i].getfrom(); //獲取郵件內(nèi)容(包含郵件內(nèi)容的html代碼) string content = (string) messages[i].getcontent(); } //關(guān)閉郵件夾對象 folder.close(); //關(guān)閉連接對象 store.close(); } } |
6、使用 javamail 發(fā)送帶圖片、附件的郵件
我們先看項目結(jié)構(gòu),在src目錄下包含圖片和附件:
然后看代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package com.ys.mail; import java.util.date; import java.util.properties; import javax.activation.datahandler; import javax.activation.filedatasource; import javax.mail.message; import javax.mail.messagingexception; import javax.mail.session; import javax.mail.transport; import javax.mail.internet.addressexception; import javax.mail.internet.internetaddress; import javax.mail.internet.mimebodypart; import javax.mail.internet.mimemessage; import javax.mail.internet.mimemultipart; import javax.mail.internet.mimeutility; public class sendmailtext_picture_enclosure { //發(fā)件人地址 //收件人地址 //發(fā)件人賬戶名 public static string senderaccount = "xxx" ; //發(fā)件人賬戶密碼 public static string senderpassword = "xxx" ; public static void main(string[] args) throws exception { //1、連接郵件服務器的參數(shù)配置 properties props = new properties(); //設(shè)置用戶的認證方式 props.setproperty( "mail.smtp.auth" , "true" ); //設(shè)置傳輸協(xié)議 props.setproperty( "mail.transport.protocol" , "smtp" ); //設(shè)置發(fā)件人的smtp服務器地址 props.setproperty( "mail.smtp.host" , "smtp.163.com" ); //2、創(chuàng)建定義整個應用程序所需的環(huán)境信息的 session 對象 session session = session.getinstance(props); //設(shè)置調(diào)試信息在控制臺打印出來 session.setdebug( true ); //3、創(chuàng)建郵件的實例對象 message msg = getmimemessage(session); //4、根據(jù)session對象獲取郵件傳輸對象transport transport transport = session.gettransport(); //設(shè)置發(fā)件人的賬戶名和密碼 transport.connect(senderaccount, senderpassword); //發(fā)送郵件,并發(fā)送到所有收件人地址,message.getallrecipients() 獲取到的是在創(chuàng)建郵件對象時添加的所有收件人, 抄送人, 密送人 transport.sendmessage(msg,msg.getallrecipients()); //5、關(guān)閉郵件連接 transport.close(); } /** * 獲得創(chuàng)建一封郵件的實例對象 * @param session * @return * @throws messagingexception * @throws addressexception */ public static mimemessage getmimemessage(session session) throws exception{ //1.創(chuàng)建一封郵件的實例對象 mimemessage msg = new mimemessage(session); //2.設(shè)置發(fā)件人地址 msg.setfrom( new internetaddress(senderaddress)); /** * 3.設(shè)置收件人地址(可以增加多個收件人、抄送、密送),即下面這一行代碼書寫多行 * mimemessage.recipienttype.to:發(fā)送 * mimemessage.recipienttype.cc:抄送 * mimemessage.recipienttype.bcc:密送 */ msg.setrecipient(mimemessage.recipienttype.to, new internetaddress(recipientaddress)); //4.設(shè)置郵件主題 msg.setsubject( "郵件主題(包含圖片和附件)" , "utf-8" ); //下面是設(shè)置郵件正文 //msg.setcontent("簡單的純文本郵件!", "text/html;charset=utf-8"); // 5. 創(chuàng)建圖片"節(jié)點" mimebodypart image = new mimebodypart(); // 讀取本地文件 datahandler dh = new datahandler( new filedatasource( "src\\mailtestpic.png" )); // 將圖片數(shù)據(jù)添加到"節(jié)點" image.setdatahandler(dh); // 為"節(jié)點"設(shè)置一個唯一編號(在文本"節(jié)點"將引用該id) image.setcontentid( "mailtestpic" ); // 6. 創(chuàng)建文本"節(jié)點" mimebodypart text = new mimebodypart(); // 這里添加圖片的方式是將整個圖片包含到郵件內(nèi)容中, 實際上也可以以 http 鏈接的形式添加網(wǎng)絡圖片 text.setcontent( "這是一張圖片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'><img src='cid:mailtestpic'/></a>" , "text/html;charset=utf-8" ); // 7. (文本+圖片)設(shè)置 文本 和 圖片"節(jié)點"的關(guān)系(將 文本 和 圖片"節(jié)點"合成一個混合"節(jié)點") mimemultipart mm_text_image = new mimemultipart(); mm_text_image.addbodypart(text); mm_text_image.addbodypart(image); mm_text_image.setsubtype( "related" ); // 關(guān)聯(lián)關(guān)系 // 8. 將 文本+圖片 的混合"節(jié)點"封裝成一個普通"節(jié)點" // 最終添加到郵件的 content 是由多個 bodypart 組成的 multipart, 所以我們需要的是 bodypart, // 上面的 mailtestpic 并非 bodypart, 所有要把 mm_text_image 封裝成一個 bodypart mimebodypart text_image = new mimebodypart(); text_image.setcontent(mm_text_image); // 9. 創(chuàng)建附件"節(jié)點" mimebodypart attachment = new mimebodypart(); // 讀取本地文件 datahandler dh2 = new datahandler( new filedatasource( "src\\mailtestdoc.docx" )); // 將附件數(shù)據(jù)添加到"節(jié)點" attachment.setdatahandler(dh2); // 設(shè)置附件的文件名(需要編碼) attachment.setfilename(mimeutility.encodetext(dh2.getname())); // 10. 設(shè)置(文本+圖片)和 附件 的關(guān)系(合成一個大的混合"節(jié)點" / multipart ) mimemultipart mm = new mimemultipart(); mm.addbodypart(text_image); mm.addbodypart(attachment); // 如果有多個附件,可以創(chuàng)建多個多次添加 mm.setsubtype( "mixed" ); // 混合關(guān)系 // 11. 設(shè)置整個郵件的關(guān)系(將最終的混合"節(jié)點"作為郵件的內(nèi)容添加到郵件對象) msg.setcontent(mm); //設(shè)置郵件的發(fā)送時間,默認立即發(fā)送 msg.setsentdate( new date()); return msg; } } |
執(zhí)行程序后,我們查看郵箱:
那么一封包含圖片(點擊圖片跳轉(zhuǎn)到指定超鏈接),和附件的郵件就生成了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/ysocean/p/7666061.html