我們常常在郵件中添加附件,以達到傳輸較大文件的目的。而上一篇文章只是將本機的一張圖片內嵌到郵件的 HTML 格式的正文當中,這樣的郵件顯得不夠豐富多彩。我們想要一封正文部分圖文并茂,而游客附帶若干附件的郵件。
下面是代碼結構中3個重要的方法:
- MimeBodyPart createAttachment(String fileName) 方法用于創建附件并返回;
- MimeBodyPart createContent(String body, String fileName) 方法用于創建正文部分并返回;
- MimeMessage createMessage(Session session) 方法用于調用上面的兩個方法生成郵件。
其實,創建一個內含附件的郵件與上一篇文章中創建正文中包含圖片的郵件的原理,甚至代碼都幾乎相同。也就是使用 JAF 框架中的 FileDataSource 類和 DataHandler 類來獲得給定路徑的資源文件,JAF 框架中的這兩個類共同協作可以獲知文件所屬的 MIME 類型,它們會正確地添加到郵件組織結構中的對應消息頭中。
不同的是:
在 HTML 格式的正文中內含圖片是使用 MimeBody.setContentID() 方法設置對應的資源文件的唯一標識符,即 MIME 協議對于郵件的結構組織格式中的 Content-ID 頭字段;
而在 MIME 郵件中添加附件是使用 MimeBodyPart.setFileName() 方法來關聯 FileSourceData 對象指向的資源文件。
程序代碼:
這個不同點在下面代碼中會用橙色背景強調指出,代碼如下:
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
|
import java.io.FileOutputStream; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; /** * 創建內含附件、圖文并茂的郵件 * @author haolloyin */ public class WithAttachmentMessage { /** * 根據傳入的文件路徑創建附件并返回 */ public MimeBodyPart createAttachment(String fileName) throws Exception { MimeBodyPart attachmentPart = new MimeBodyPart(); FileDataSource fds = new FileDataSource(fileName); attachmentPart.setDataHandler( new DataHandler(fds)); attachmentPart.setFileName(fds.getName()); return attachmentPart; } /** * 根據傳入的郵件正文body和文件路徑創建圖文并茂的正文部分 */ public MimeBodyPart createContent(String body, String fileName) throws Exception { // 用于保存最終正文部分 MimeBodyPart contentBody = new MimeBodyPart(); // 用于組合文本和圖片,"related"型的MimeMultipart對象 MimeMultipart contentMulti = new MimeMultipart( "related" ); // 正文的文本部分 MimeBodyPart textBody = new MimeBodyPart(); textBody.setContent(body, "text/html;charset=gbk" ); contentMulti.addBodyPart(textBody); // 正文的圖片部分 MimeBodyPart jpgBody = new MimeBodyPart(); FileDataSource fds = new FileDataSource(fileName); jpgBody.setDataHandler( new DataHandler(fds)); jpgBody.setContentID( "logo_jpg" ); contentMulti.addBodyPart(jpgBody); // 將上面"related"型的 MimeMultipart 對象作為郵件的正文 contentBody.setContent(contentMulti); return contentBody; } /** * 根據傳入的 Seesion 對象創建混合型的 MIME消息 */ public MimeMessage createMessage(Session session) throws Exception { String from = test_hao @163 .com; String subject = "創建內含附件、圖文并茂的郵件!" ; String body = "<h4>內含附件、圖文并茂的郵件測試?。?!</h4> </br>" + "<a href = http://haolloyin.blog.51cto.com/> 螞蟻</a></br>" + "<img src = \"cid:logo_jpg\"></a>" ; MimeMessage msg = new MimeMessage(session); msg.setFrom( new InternetAddress(from)); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); msg.setSubject(subject); // 創建郵件的各個 MimeBodyPart 部分 MimeBodyPart attachment01 = createAttachment( "F:\\java\\Snake.java" ); MimeBodyPart attachment02 = createAttachment( "F:\\java\\meng.mp3" ); MimeBodyPart content = createContent(body, "F:\\java\\logo.jpg" ); // 將郵件中各個部分組合到一個"mixed"型的 MimeMultipart 對象 MimeMultipart allPart = new MimeMultipart( "mixed" ); allPart.addBodyPart(attachment01); allPart.addBodyPart(attachment02); allPart.addBodyPart(content); // 將上面混合型的 MimeMultipart 對象作為郵件內容并保存 msg.setContent(allPart); msg.saveChanges(); return msg; } // 測試生成郵件 public static void main(String[] args) throws Exception { WithAttachmentMessage mail = new WithAttachmentMessage(); Session session = Session.getDefaultInstance( new Properties()); MimeMessage message = mail.createMessage(session); message.writeTo( new FileOutputStream( "withAttachmentMail.eml" )); } } |
編譯、運行生成 withAttachmentMail.eml 文件,雙擊打開,如下圖:
看看上面用 Outlook 打開生成的文件,在附件欄里面就有一個 .java 源文件和一首 MP3 文件了。
打開郵件的原始內容:
查看生成的郵件的原始內容,點擊“文件”、“屬性”、“郵件來源”或者使用 EditPlus 、UltraEdit 等文本編輯器直接打開也行,下面是原始內容:
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
|
From: test_hao @163 .com To: test_hao @sina .cn Message-ID: < 56667.2 . 1279677956578 .JavaMail.Administrator @WWW -1477FF1578B> Subject: =?GBK?B?tLS9qMTauqy4vbz+oaLNvM7EsqLDr7XE08q8/qOh?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary= "----=_Part_1_13249998.1279677956546" ------=_Part_1_13249998. 1279677956546 Content-Type: application/octet-stream; name=Snake.java Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=Snake.java // 省略被 BASE64 轉碼后的 Snake.java 附件內容 ------=_Part_1_13249998. 1279677956546 Content-Type: application/octet-stream; name=meng.mp3 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=meng.mp3 // 省略被 BASE64 轉碼后的 meng.java 附件內容 ------=_Part_1_13249998. 1279677956546 Content-Type: multipart/related; boundary= "----=_Part_0_3373112.1279677956546" ------=_Part_0_3373112. 1279677956546 Content-Type: text/html;charset=gbk Content-Transfer-Encoding: quoted-printable <h4>=C4=DA=BA=AC=B8=BD=BC=FE=A1=A2=CD=BC=CE=C4=B2=A2=C3=AF=B5=C4=D3=CA=BC= =FE=B2=E2=CA=D4=A3=A1=A3=A1=A3=A1</h4> </br><a href =3D http: //haolloyin.bl= og.51cto.com/> =C2=EC=D2=CF</a></br><img src =3D "cid:logo_jpg" ></a> ------=_Part_0_3373112. 1279677956546 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-ID: logo_jpg // 省略被 BASE64 轉碼后的郵件正文部分內嵌的 .jpg 圖片的內容 ------=_Part_0_3373112. 1279677956546 -- ------=_Part_1_13249998. 1279677956546 -- |
重要部分已經用背景顏色指出來了,有興趣的可以深入了解一下 MIME 協議對郵件結構組織的規范格式。