JavaMaill:使用MIME协议创建内含图片的复杂邮件

像上一篇文章那样,我们只能创建一封封只包含纯文本或者HTML格式的文本邮件,这远远不能满足我们现在的需要,我们经常想要把本机上的图片、相片包含在邮件的正文部分,或者是直接将自己制作的贺卡等作为邮件正文发送给我们的朋友。

想要在邮件中包含图片、音频、视频等其他格式的文件,就不能再简单地使用 RFC 文档来对邮件结构、内容进行描述了,因为 RFC 只能描述普通的文本,而且一旦遇到单独一行的句号“.”时,SMTP 服务器就会以此为邮件正文部分的结束符,因此很大可能会导致邮件信息的丢失。

withPictureMail01  在上图中,我们看到 BodyPart 还可以再包含 MultiPart ,很明显这是一种组合结构、模式,或者说成树状结构。

注:JavaMail01

 

好了,用代码来说明问题,实现一下,不管是否合适,我还是在代码中写上较多注释,其中有一些事必须注意的,代码如下:

  1. /**  
  2.  * 创建内含图片的邮件,保存为 Outlook 的 ".eml" 文件  
  3.  * @author haolloyin  
  4.  */ 
  5. public class WithPictureMessage {  
  6.     public static void main(String[] args) throws Exception{  
  7.  
  8.         String from = "test_hao@sina.cn";  
  9.         String to = "test_hao@163.com";  
  10.         String subject = "创建一个内含图片的邮件!";  
  11.         String body = "<h4>内含图片的邮件测试!!!</h4> " +  
  12.         "<a href = http://haolloyin.blog.51cto.com/> 蚂蚁</a></br></br>" +   
  13.         "<a href = http://haolloyin.blog.51cto.com/>" +  
  14.         "<img src = \"cid:;  
  15.         /*  
  16.          *  上面的 cid 是指 MIME 协议中的 Content-ID 头,它是  
  17.          *  对于文件资源的唯一标识符,下面的          *  中传入的 ID 号就必须与这个haolloyin_logo_jpg相一致  
  18.          */ 
  19.           
  20.         // 创建该邮件应用程序所需的环境信息以及会话信息  
  21.         Session session = Session.getDefaultInstance(new Properties());  
  22.           
  23.         // 以下几句是设置邮件的基本信息  
  24.         MimeMessage msg = new MimeMessage(session);       
  25.         msg.setFrom(new InternetAddress(from));       
  26.         msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));  
  27.         msg.setSubject(subject);  
  28.         msg.setSentDate(new Date());  
  29.           
  30.         /*  
  31.          *  创建一个子类型为 “         *  其实 MimeMultipart 类还有另外两种子类型,请自行  
  32.          *  查阅并比较其中的适用场景  
  33.          */ 
  34.         MimeMultipart multipart = new MimeMultipart("related");  
  35.           
  36.         /*  
  37.          * 创建一个表示 HTML 正文部分的 MimeBodyPart 对象,   
  38.          * 并加入 到上一语句创建的 MimeMultiPart 对象中,  
  39.          * 由于 HTML 正文中包含中文,故下面应该         */ 
  40.         MimeBodyPart htmlBodyPart = new MimeBodyPart();  
  41.         htmlBodyPart.setContent(body, "text/html;charset=gbk");  
  42.         multipart.addBodyPart(htmlBodyPart);  
  43.           
  44.         /*  
  45.          *  创建一个表示图片文件的 MimeBodyPart 对象,  
  46.          *  并加入 到上面所创建的 MimeMultiPart 对象中,  
  47.          *  使用 JAF 框架中的 FileDataSource 类获取图片文件源,  
  48.          *  它         */ 
  49.         MimeBodyPart jpgBodyPart = new MimeBodyPart();  
  50.         FileDataSource fds = new FileDataSource("F:\\java\\haolloyin_logo.jpg");  
  51.         jpgBodyPart.setDataHandler(new DataHandler(fds));  
  52.         jpgBodyPart.setContentID("haolloyin_logo_jpg");  
  53.           
  54.         multipart.addBodyPart(jpgBodyPart);  
  55.           
  56.         /*  
  57.          *  这里不用再设置字符集了,因为上面的 HTML MimeBodyPart 对象中  
  58.          *  已经设置了,而图片文件的因为使用了 DataSource 对象,即 JAF 框架  
  59.          *  中的具体数据处理操作类,能够自动判断获知数据的 MIME 类型  
  60.          */ 
  61.         msg.setContent(multipart);  
  62.           
  63.         // 保存对邮件的修改并写入文件中  
  64.         msg.saveChanges();        
  65.         msg.writeTo(new FileOutputStream("withPictureMail.eml"));  
  66.     }  

编译、运行,生成 withPictureMail.eml 文件,双击打开,如下图:

withPictureMail02

 

image

在代码中的许多注释是比较重要的,必须要注意。此外,还可像上一篇文章中在 Outlook 中查看该 MIME 邮件的原始内容,其中应该既有 quoted-printable 编码也有 BASE64 编码方式,有兴趣的还可以看看各个消息头的格式是怎样的。

小结:

1、明白当 MIME 邮件需要附上多种格式(不仅仅是纯文本)的资源文件时,它是运用了层层嵌套的组合结构来表示、组织各个资源文件的;

2、在代码中的许多注释就是很重要的注意点了,必须掌握。

posted @ 2015-08-18 22:45  剑芒  阅读(263)  评论(0编辑  收藏  举报