JavaMail API使用javax.mail.Message类来表示一封邮件,Message类是一个抽象类,所以我们需要使用其子类javax.mail.internet.MimeMessage类来创建Message类的实例对象,如果我们创建的是一个简单文本邮件,那么MimeMessage类就可以满足我们的需求了,但是如果需要创建一封包含内嵌资源或者是带附件的复杂邮件,则需要使用到JavaMail API中的MimeMessage、javax.mail.internet.MimeBodyPart和javax.mail.internet.MimeMultipart等类。

1、MimeMessage类表示整封邮件

2、MimeBodyPart类表示邮件的一个MIME消息

3、MimeMultipart类表示一个由多个MIME消息组合成的组合MIME消息。

这三个类的工作关系如下图所示:


虽然应用程序开发者在使用JavaMailAPI创建邮件内容时,通常只需要使用MimeMessage,MimeBodyPart和MimeMultipart这3个主要的类,但是了解他们的类继承关系也是必要的。下图列出了这三个类的继承关系以及常用方法。

下面用javax.mail.internet.MimeMessage类来创建一封简单的文本邮件,

  1. import java.util.Date;
  2. import java.util.Properties;
  3. import javax.mail.Message;
  4. import javax.mail.Session;
  5. import javax.mail.internet.InternetAddress;
  6. import javax.mail.internet.MimeMessage;
  7. import java.io.FileOutputStream;
  8.  
  9. public class TextMessage {
  10. public static void main(String[] args) throws Exception {
  11. String from = "123456@qq.com";
  12. String to = "123456@163.com";
  13. String subject = "test";
  14. String body = "test!!!";
  15.  
  16. // 创建Session实例对象
  17. Session session = Session.getDefaultInstance(new Properties());
  18. // 创建MimeMessage实例对象
  19. MimeMessage msg = new MimeMessage(session);
  20. // 设置发件人
  21. msg.setFrom(new InternetAddress(from));
  22. // 设置收件人
  23. msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
  24. // 设置发送日期
  25. msg.setSentDate(new Date());
  26. // 设置邮件主题
  27. msg.setSubject(subject);
  28. // 设置纯文本内容的邮件正文
  29. msg.setText(body);
  30. // 保存并生成最终的邮件内容
  31. msg.saveChanges();
  32. // 把MimeMessage对象中的内容写入到文件中
  33. msg.writeTo(new FileOutputStream("c:\\test.eml"));
  34. }
  35. }

我们用邮件客户端(这里用foxmail)打开C盘下面的test.eml文件,可以看到如下信息,说明我们的邮件创建成功。

下面简单解释一下上面出现的一些类

1、MimeMessage类:上面介绍过MimeMessage是Message类的一个具体实现类,用来创建Message类的实例对象,这里构造函数传入了一个Session对象作为参数;

2、Session类:该对象用于收集客户端与邮件服务器之间的网络连接信息和定义整个邮件程序所需的环境信息,这些信息作为Session对象的属性保存在Session对象中,Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息,由于Session类的构造方法是私有的,所以我们使用Session类提供的getDefaultInstance()这个静态工厂方法获得一个默认的Session对象;

3、Properties类:该类表示了一个持久的属性集,用于存放相关键值对信息作为参数来创建Session对象,这里构造了一个空的集合作为参数;

4、InternetAddress类:该类是抽象类Address类的一个子类,用来创建一个邮件地址;

5、RecipientType类:该类是Message类的一个内部类,该类有3个静态变量,TO表示收件人,CC表示抄送人(收件人知道抄送的人),BCC表示密送人(收件人不知道密送的人)。

上面的邮件只是包含了简单的文本,有时候我们需要使用HTML文件来丰富我们的邮件正文,例如使用HTML标签来对邮件正文进行排版,使用HTML标签在邮件正文中引入一些图片或者是声音等。下面这段代码创建了一个包含HTML格式的邮件

  1. import java.util.Date;
  2. import java.util.Properties;
  3. import javax.mail.Message;
  4. import javax.mail.Session;
  5. import javax.mail.internet.InternetAddress;
  6. import javax.mail.internet.MimeMessage;
  7. import java.io.FileOutputStream;
  8.  
  9. public class HtmlMessage {
  10. public static void main(String[] args) throws Exception {
  11. String from = "123456@qq.com";
  12. String to = "123456@163.com";
  13. String subject = "test";
  14. String body = "<h4>欢迎大家阅读此邮件</h4>";
  15. // 创建Session实例对象
  16. Session session = Session.getDefaultInstance(new Properties());
  17. // 创建MimeMessage实例对象
  18. MimeMessage msg = new MimeMessage(session);
  19. // 设置发件人
  20. msg.setFrom(new InternetAddress(from));
  21. // 设置收件人
  22. msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
  23. // 设置发送日期
  24. msg.setSentDate(new Date());
  25. // 设置邮件主题
  26. msg.setSubject(subject);
  27. // 设置HTML格式的邮件正文
  28. msg.setContent(body, "text/html;charset=gb2312");
  29. // 保存并生成最终的邮件内容
  30. msg.saveChanges();
  31. // 把MimeMessage对象中的内容写入到文件中
  32. msg.writeTo(new FileOutputStream("c:\\test.eml"));
  33. }
  34. }

我们再用foxmail打开test.eml,显示如下

与之前代码不同的地方只是我们设置邮件内容的时候用setContent方法代替了setText方法,并且指定了邮件正文的MIME类型为text/html。

现在我们学会了创建含有HTML标签的邮件了,不过有时我们可能需要在邮件中插入一些图片来更直观的表达我们的意思,那么这时候我们就需要用到MimeMultipart类与MimeBodyPart类了

  1. import java.io.FileOutputStream;
  2. import java.util.Properties;
  3. import javax.activation.DataHandler;
  4. import javax.activation.FileDataSource;
  5. import javax.mail.Message;
  6. import javax.mail.Session;
  7. import javax.mail.internet.InternetAddress;
  8. import javax.mail.internet.MimeBodyPart;
  9. import javax.mail.internet.MimeMessage;
  10. import javax.mail.internet.MimeMultipart;
  11.  
  12. public class PictureMessage {
  13. public static void main(String[] args) throws Exception {
  14. String from = "123456@qq.com";// 发件人地址
  15. String to = "123456@163.com"; // 收件人地址
  16. String subject = "HTML邮件";
  17. String body = "<a href=http://www.cnblogs.com>" + "欢迎大家访问博客园</a></br>"
  18. + "<img src=\"c:\\dog.jpg\">";
  19.  
  20. Session session = Session.getDefaultInstance(new Properties());
  21. // 创建MimeMessage对象,并设置各种邮件头字段
  22. MimeMessage message = new MimeMessage(session);
  23. message.setFrom(new InternetAddress(from));
  24. message.setRecipients(Message.RecipientType.TO,
  25. InternetAddress.parse(to));
  26. message.setSubject(subject);
  27.  
  28. // 创建一个子类型为"related"的MimeMultipart对象。
  29. MimeMultipart multipart = new MimeMultipart("related");
  30.  
  31. /*
  32. * 创建一个表示HTML正文的MimeBodyPart对象, 并将它加入到前面创建的MimeMultipart对象中
  33. */
  34. MimeBodyPart htmlBodyPart = new MimeBodyPart();
  35. htmlBodyPart.setContent(body, "text/html;charset=gb2312");
  36. multipart.addBodyPart(htmlBodyPart);
  37.  
  38. /*
  39. * 创建一个表示图片内容的MimeBodyPart对象, 并将它加入到前面创建的MimeMultipart对象中
  40. */
  41. MimeBodyPart gifBodyPart = new MimeBodyPart();
  42. FileDataSource fds = new FileDataSource("c:\\dog.jpg");
  43. gifBodyPart.setFileName(fds.getName());
  44. gifBodyPart.setDataHandler(new DataHandler(fds));
  45. multipart.addBodyPart(gifBodyPart);
  46.  
  47. /*
  48. * 将MimeMultipart对象设置为整个邮件的内容, 要注意调用saveChanges方法进行更新
  49. */
  50. message.setContent(multipart);
  51. message.saveChanges();
  52.  
  53. // 把MimeMessage对象中的内容写入到文件中
  54. message.writeTo(new FileOutputStream("c:\\PictureMessage.eml"));
  55. }
  56. }

代码看起来似乎有点小复杂,可以再看看上面提到的MimeMessage,MimeMultipart与MimeBodyPart这三个类之间的关系图,这样会更会容易理解上面的代码,我们打开PictureMessage.eml,看到如下信息,说明我们成功的创建了一个带有图片的邮件了,并且该图片以附件的形式包含在邮件中了

MimeMultipart有两种构造函数,

  1. public MimeMultipart()
  2. public MimeMultipart(String subtype)

第一种是无参数的,其默认的实例对象的MIME类型为mixed,第二种制定一个类型来创建MimeMultipart类的实例对象,其有三种常用的类型:mixed,related,alternative,这三种类型在MIME中的组合关系如下所示:

现在我们用上面所示的这种组合关系来创建一封带有附件,并且正文中带有内嵌资源的邮件

  1. import java.io.FileOutputStream;
  2. import java.util.Properties;
  3. import javax.activation.DataHandler;
  4. import javax.activation.FileDataSource;
  5. import javax.mail.Message;
  6. import javax.mail.Session;
  7. import javax.mail.internet.InternetAddress;
  8. import javax.mail.internet.MimeBodyPart;
  9. import javax.mail.internet.MimeMessage;
  10. import javax.mail.internet.MimeMultipart;
  11.  
  12. public class ComplexMessage {
  13. public static void main(String[] args) throws Exception {
  14. Session session = Session.getDefaultInstance(new Properties());
  15. MimeMessage message = createMessage(session);
  16. message.writeTo(new FileOutputStream("c:\\ComplexMessage.eml"));
  17. }
  18.  
  19. public static MimeMessage createMessage(Session session) throws Exception {
  20. String from = "123456@qq.com";// 发件人地址
  21. String to = "123456@163.com"; // 收件人地址
  22. String subject = "HTML邮件"; // 邮件主题
  23. String body = "<a href=http://www.cnblogs.com>" + "欢迎大家访问博客园</a></br>"
  24. + "<img src=\"c:\\dog.jpg\">";
  25.  
  26. MimeMessage message = new MimeMessage(session);
  27. message.setFrom(new InternetAddress(from));
  28. message.setRecipients(Message.RecipientType.TO,
  29. InternetAddress.parse(to));
  30. message.setSubject(subject);
  31.  
  32. // 创建代表邮件正文和附件的各个MimeBodyPart对象
  33. MimeBodyPart contentPart = createContent(body, "c:\\dog.jpg");
  34. // 下面的附件可以是视频或者是音频
  35. MimeBodyPart attachPart1 = createAttachment("c:\\音乐.MP3");
  36. MimeBodyPart attachPart2 = createAttachment("c:\\视频.avi");
  37.  
  38. // 创建用于组合邮件正文和附件的MimeMultipart对象
  39. MimeMultipart allMultipart = new MimeMultipart("mixed");
  40. allMultipart.addBodyPart(contentPart);
  41. allMultipart.addBodyPart(attachPart1);
  42. allMultipart.addBodyPart(attachPart2);
  43.  
  44. // 设置整个邮件内容为最终组合出的MimeMultipart对象
  45. message.setContent(allMultipart);
  46. message.saveChanges();
  47. return message;
  48. }
  49.  
  50. public static MimeBodyPart createContent(String body, String filename)
  51. throws Exception {
  52. /*
  53. * 创建代表组合MIME消息的MimeMultipart对象, 和将该MimeMultipart对象保存到的MimeBodyPart对象
  54. */
  55. MimeBodyPart contentPart = new MimeBodyPart();
  56. MimeMultipart contentMultipart = new MimeMultipart("related");
  57.  
  58. /*
  59. * 创建用于保存HTML正文的MimeBodyPart对象, 并将它保存到MimeMultipart中
  60. */
  61. MimeBodyPart htmlBodyPart = new MimeBodyPart();
  62. htmlBodyPart.setContent(body, "text/html;charset=gb2312");
  63. contentMultipart.addBodyPart(htmlBodyPart);
  64.  
  65. /*
  66. * 创建用于保存图片的MimeBodyPart对象, 并将它保存到MimeMultipart中
  67. */
  68. MimeBodyPart gifBodyPart = new MimeBodyPart();
  69. FileDataSource fds = new FileDataSource(filename);
  70. gifBodyPart.setDataHandler(new DataHandler(fds));
  71. contentMultipart.addBodyPart(gifBodyPart);
  72.  
  73. // 将MimeMultipart对象保存到MimeBodyPart对象中
  74. contentPart.setContent(contentMultipart);
  75. return contentPart;
  76. }
  77.  
  78. public static MimeBodyPart createAttachment(String filename)
  79. throws Exception {
  80. // 创建保存附件的MimeBodyPart对象,并加入附件内容和相应信息
  81. MimeBodyPart attachPart = new MimeBodyPart();
  82. FileDataSource fds = new FileDataSource(filename);
  83. attachPart.setDataHandler(new DataHandler(fds));
  84. attachPart.setFileName(fds.getName());
  85. return attachPart;
  86. }
  87. }

打开ComplexMessage.eml文件,可以看到如下内容,

现在我们学会了如何创建一封纯文本的邮件,带有HTML格式的邮件,以及带有内嵌图片与附件的邮件了,下一篇JavaMail入门第三篇 发送邮件将介绍如何发送邮件。

JavaMail入门第二篇 创建邮件的更多相关文章

  1. JavaMail入门第一篇 邮件简介及API概述

    现如今,电子邮件在我们的生活当中扮演着越来越重要的角色,我们每个人几乎都会与其打交道(至少时不时我们都会接收到莫名其妙的垃圾邮件),在工作中,使用邮件进行交流沟通,可以使我们的工作有迹可循,也显的较为 ...

  2. ElasticSearch入门 第二篇:集群配置

    这是ElasticSearch 2.4 版本系列的第二篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  3. 微信js框架第二篇(创建完整界面布局)

    接着昨天的继续谈关于微信新出的这个js框架,今天主要谈一个页面的创建到布局的详细步骤. 一.创建一个完整页面       页面你可以创建在项目的任何节点,只要你在入口文件正确引入创建该页面的路径就可使 ...

  4. Cocos2d-x3.0游戏实例之《别救我》第二篇——创建物理世界

    这篇我要给大家介绍两个知识点: 1. 创建游戏物理世界 2. 没了(小若:我噗) 害怕了?不用操心.这太简单了~! 笨木头花心贡献.啥?花心?不呢.是用心~ 转载请注明,原文地址:http://www ...

  5. Windows下FFmpeg快速入门 <第二篇>

    FFmpeg简介 FFmpeg是什么? FFmpeg是用于录制.转换和流化音频和视频的完整解决方案, 包括 libavcodec ,一套领先的音/视频编解码类库.FFmpeg 在Linux上开发,当可 ...

  6. Android JNI入门第二篇——Java参数类型与本地参数类型对照

    前面一篇通过简单的例子介绍了android中JNI的使用.这一篇从基础上了解一些Java参数类型与本地参数类型区别. 1)        java中的返回值void和JNI中的void是完全对应的哦! ...

  7. Hadoop入门第二篇-MapReduce学习

    mapreduce是一种计算模型,是google的一篇论文向全世界介绍了MapReduce.MapReduce其实可以可以用多种语言编写Map或Reduce程序,因为hadoop是java写的,所以通 ...

  8. Html/Css(新手入门第二篇)

    一.在实际工作中,都是一个团队在做项目,不是一个人在工作.多人协作,就是每个团队都有自己 的命名习惯.1.css选择符命名,规范.2.都有命名规范文档. 二.css选择符作用:指定css样式所作用对象 ...

  9. Android Studio开发第二篇创建新项目

    创建新项目很简单,File-New-New Project,这个没什么好说的跟Eclipse都差不都. 第二步SDK选择,有手机平板还有Wear,TV,汽车Auto,谷歌眼镜等几个种平台,这里就先选择 ...

随机推荐

  1. SQLSERVER吞噬内存解决记录

    现在手上有一个不大不小的系统,运行了一段时间,因为是24*7不断运行,所以内存逐渐增高,慢慢的会飙到95%以上,然后不得不重启电脑,因为用的是云,怕虚拟机重启down掉起不来,重启操作还只能在凌晨4. ...

  2. iOS开发问题之Could not instantiate class named NSLayoutConstraint

    这个问题在ios6.0之前的版本中运行会出现,因为使用Xcode 4.5之后的版本新建项目默认是选中AutoLayout的,但这个特性是在iOS6.0之后的版本中才支持的. 解决办法是选中.stroy ...

  3. mysql日志问题定位实用命令

    show engine innodb status查看日志 select @@version;查看版本(不同版本性能优化不同) SELECT * FROM information_schema.inn ...

  4. 无法打开包括文件:'atlrx.h'的解决办法

    VS 2008中由于将ALT项目的部分代码剥离出去成为了独立的开源项目,需要用到ALT中正则表达式等功能就需要手动下载. 我不是第一个遇到这个问题的,所以已经有前人给出了解决方案. 可到http:// ...

  5. HTML5新特性之跨文档消息传输

    1.同域限制 所谓“同域限制”是指,出于安全考虑,浏览器只允许脚本与同样协议.同样域名.同样端口的地址进行通信. 2.window.postMessage方法 浏览器限制不同窗口(包括iFrame窗口 ...

  6. Java IO 之 OutputStream源码

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  7. WPF国际化(多语言)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  8. 自动化测试管理平台ATMS(V2.0.2_8.19)下载

    自动化测试管理平台ATMS(V2.0.2_8.19)下载 http://www.automationqa.com/forum.php?mod=viewthread&tid=2791

  9. EETOP中关于Gm仿真的一些帖子的总结

    1. cadence画gm曲线 电路里,要把漏的电源dc值设置成变量,比如叫vds,计算器,info标签,点op,然后点管子,在op窗口点list,选gm,然后把这个公式弄到ADE的outputs那里 ...

  10. Xamarin.Forms中的ListView的ItemTrapped事件与ItemSelected事件的区别

    今天对Xamarin.Forms中的ListView的两个事件(ItemTrapped和ItemSelected)做了小小的研究,发现有以下几点区别: 1.ItemTrapped事件会优先被触发. 2 ...