邮件原理与JavaMail开发(二)——使用JavaMail创建邮件和发送邮件

来源:互联网 发布:一骑当千动作数据 编辑:程序博客网 时间:2024/05/17 00:57

在上一篇文章中我们就已经讲解过RFC822文档规范了,但讲解的不够仔细,所以我们该全面而细致地叙述该文档规范了,那这篇文章就以它作为开头展开吧!

RFC882文档简单说明

RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔。
邮件头包含的内容有:

  • from字段:用于指明发件人
  • to字段:用于指明收件人
  • subject字段:用于说明邮件主题
  • cc字段:抄送,将邮件发送给收件人的同时抄送给另一个收件人,收件人可以看到邮件抄送给了谁。
  • bcc字段:密送,将邮件发送给收件人的同时将邮件秘密发送给另一个收件人,收件人无法看到邮件密送给了谁。

邮件体指的就是邮件的具体内容。
提示:可利用RFC822文档漏洞发送假冒邮件
在上一篇文章中,我们是使用telnet客户端连接上163的邮件服务器然后发一封Email到sina的邮箱中去,现在我们来编写java程序来做这件事情,但这需要我们熟悉socket编程,但我已经忘记了,哈哈哈!!!

public class Demo {    public static void main(String[] args) throws Exception {        // yerenyuan10001@163.com向i_beautifulman@sina.com发送一封Email        Socket socket = new Socket("smtp.163.com", 25);        // 通过br读取服务器回送的数据        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));        // 通过out向服务器写数据        OutputStream out = socket.getOutputStream();        System.out.println(br.readLine());        out.write("ehlo hello\r\n".getBytes());        System.out.println(br.readLine());        System.out.println(br.readLine());        System.out.println(br.readLine());        System.out.println(br.readLine());        System.out.println(br.readLine());        System.out.println(br.readLine());        System.out.println(br.readLine());        out.write("auth login\r\n".getBytes());        System.out.println(br.readLine());        out.write("eWVyZW55DEWREdWFuMTAwMDE=\r\n".getBytes()); // 用户名必须是经过base64编码处理        System.out.println(br.readLine());        out.write("MTAwMDF5DEREWTRZXJlbnl1YW4=\r\n".getBytes()); // 密码也必须是经过base64编码处理        System.out.println(br.readLine());        out.write("mail from: <yerenyuan10001@163.com>\r\n".getBytes());        System.out.println(br.readLine());        out.write("rcpt to: <i_beautifulman@sina.com>\r\n".getBytes());        System.out.println(br.readLine());        out.write("data\r\n".getBytes());        System.out.println(br.readLine());        out.write("from: <yerenyuan10001@163.com>\r\nto: <i_beautifulman@sina.com>\r\nsubject: my love\r\n\r\nhello my lover\r\n".getBytes());        out.write(".\r\n".getBytes());        System.out.println(br.readLine());        out.write("quit\r\n".getBytes());        System.out.println(br.readLine());        br.close();        out.close();        socket.close();    }}

运行该程序,然后登陆到i_beautifulman@sina.com邮箱当中,就可以收取到由yerenyuan10001@163.com发送的Email了,如下图所示:
这里写图片描述

MIME协议简单介绍

在我们的实际开发当中,一封邮件既可能包含图片,又可能包含有附件,在这样的情况下,RFC882文档规定的邮件格式就无法满足要求了,毕竟RFC882文档是70年代的产物,已不符合如今的开发需求了,这时就应运而生了MIME协议。
MIME协议是对RFC822文档的升级和补充,它描述了如何生产一封复杂的邮件。通常我们把MIME协议描述的邮件称之为MIME邮件MIME协议描述的数据称之为MIME消息
对于一封复杂邮件,如果包含了多个不同的数据,MIME协议规定了要使用分隔线对多段数据进行分隔,并使用Content-Type头字段对数据的类型、以及多个数据之间的关系进行描述。

MIME协议常用头字段

Content-type头字段

  • 描述数据的类型
    以“主类型/子类型”的形式出现,主类型有text、image、audio、video、application、message等,分别表示文本、图片、音频、视频、应用程序、组合结构、消息等。每个主类型下面都有多个子类型,例如text主类型包含plain、html、xml、css等子类型。
  • 描述多个数据之间的关系
    • multipart/related:描述(多个)数据之间的关系是关联关系。
    • multipart/mixed:描述(多个)数据之间没有关系,但没有关系也是一种关系。
    • multipart/alternative:描述(多个)数据之间的关系是二选其一的关系,这种关系用到的是最少的。

Content-Disposition头字段

Content-Disposition头字段用于指定邮件阅读程序处理数据内容的方式,有inline和attachment两种标准方式,inline表示直接处理,而attachment表示当作附件处理。如果将Content-Disposition设置为attachment,在其后还可以指定filename属性,如下所示:

Content-Disposition: attachment; filename=“1.bmp”

上面的MIME头字段表示MIME消息体的内容为邮件附件,附件名“1.bmp”。

Content-ID头字段

Content-ID头字段用于为“multipart/related”组合消息中的内嵌资源指定一个唯一标识号,在HTML格式的正文中可以使用这个唯一标识号来引用该内嵌资源。例如,假设将一个表示内嵌图片的MIME消息的Content-ID头字段设置为如下形式:

Content-ID: it315logo_gif

那么,在HTML正文中就需要使用如下HTML语句来引用该图片资源:

<img src="cid:it315logo_gif">

注意,在引用Content-ID头字段标识的内嵌资源时,要在资源的唯一标识号前面加上“cid:“,以说明要采用唯一标识号对资源进行引用。

使用JavaMail API创建邮件

JavaMail创建的邮件是基于MIME协议的。因此可以使用JavaMail创建出包含图片,包含附件的复杂邮件。

邮件组织结构相关的API

  • MimeMessage类表示整封邮件。
  • MimeBodyPart类表示邮件的一个MIME消息。(即保存邮件某一部分数据的容器)
  • MimeMultipart类表示一个由多个MIME消息组合成的组合MIME消息。(即保存MimeBodyPart的容器)

用图来表示会更加清晰:
这里写图片描述

接下来到了创建邮件的时刻了,我们首先编写一个创建邮件测试项目,准备测试环境,如下:
这里写图片描述

  • javax.mail.jar:使用JavaMail API创建邮件和发送邮件所需的jar包。
    JavaMail API,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是SUN发布的用来处理email的API,它可以方便地执行一些常用的邮件传输。我们可以基于JavaMail开发出类似于Microsoft Outlook的应用程序。
    人们常说J2EE技术有13种,JavaMail就是其中一种。
  • activation.jar:与jaf技术相关jar包。
    jaf也是J2EE 13种技术中的一种。

创建简单邮件

使用JavaMail API创建最简单邮件(即纯文本邮件)的代码:

public class SimpleMail {    /*     * 简单邮件     */    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        message.setContent("hello hello liayun", "text/html");        message.saveChanges();        // 将创建好的邮件写入到C盘以文件的形式进行保存        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

运行该程序,我们可以在C盘下看到有生成一个1.eml文件,如要打开该文件,可使用Microsoft Outlook这样的客户端工具,因为Outlook支持后缀名为.eml的文件。由于我本人没安装这样的东西,所以非常遗憾看不了其中的内容了。

创建包含内嵌图片的邮件

使用JavaMail API创建包含内嵌图片的邮件的代码:

public class ImageMail {    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        // 创建邮件中的数据        // 创建正文        MimeBodyPart text = new MimeBodyPart();        text.setContent("hello liayun<br/><img src='cid:1.jpg'><br/>I love you", "text/html");        // 创建图片        MimeBodyPart image = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/1.jpg")); // jaf技术        /*         * new一个数据处理器与图片相关联,然后将数据处理器传递给setDataHandler方法,         * 该方法会自动从数据处理器里面获取数据然后弄到image对象中去。         *          * 记住:还要说明这个数据的类型,但是这儿是不需要设置的,因为数据处理器非常聪明,         * 它会自动感知它所关联的数据源的类型,setDataHandler方法除了从数据处理器里面获取数据之外,         * 它还会调用数据处理器的方法来获取它感知的数据类型,帮我们设置好         */        image.setDataHandler(dh);         image.setContentID("1.jpg"); // 设置ID        // 描述这两部分数据之间的关系        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(text);        mm.addBodyPart(image);        mm.setSubType("related"); // 描述这两部分数据之间的关系是关联关系        message.setContent(mm); // 设置邮件内容        message.saveChanges(); // 保存邮件        // 将创建好的邮件写入到C盘以文件的形式进行保存        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

运行该程序,我们可以在C盘下看到有生成一个1.eml文件。
但我们还有另一种创建包含内嵌图片的邮件的方式,代码如下:

public class ImageMail2 {    /*     * 创建一封带图片的邮件     */    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        // message.setContent("hello<br/><img src='c:\\1.jpg'>", "text/html");        message.setContent("hello<br/><img src='http://localhost:8080/mail/1.jpg'>", "text/html");        message.saveChanges();        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

但我们一般不推荐这样的做法,这样做容易泄露我们的一些信息,道理我就不详述了,懂的自然懂。

创建包含附件的邮件

使用JavaMail API创建包含附件的邮件的代码:

public class AttachMail {    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        // 创建封装正文数据的bodypart        MimeBodyPart text = new MimeBodyPart();        text.setContent("hello liayun I love you", "text/html");        // 创建封装附件数据的bodypart        MimeBodyPart attach = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/1.mp3"));        attach.setDataHandler(dh);        // 只要调用了setFileName方法,JavaMail这套API就会自动帮我们生成Content-Disposition这个头字段        attach.setFileName(dh.getName()); // 通过数据处理器获得附件的附件名,然后再设置附件名        // 描述这两部分数据之间的关系,但正文和附件之间是没关系的,没关系也是一种关系,即mixed        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(text);        mm.addBodyPart(attach);        mm.setSubType("mixed");        message.setContent(mm);        message.saveChanges();        // 将创建好的邮件写入到C盘以文件的形式进行保存        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

运行该程序,我们可以在C盘下看到有生成一个1.eml文件。

包含内嵌图片和附件的复杂邮件

说这样的邮件是世界上最复杂的邮件也不为过,那这样的复杂邮件到底该怎样生成呢?其实也不算多复杂,只要弄懂下面这张图就行了。
这里写图片描述
使用JavaMail API创建包含内嵌图片和附件的复杂邮件的代码:

public class ComplexMail {    /*     * 世界上最复杂的邮件     */    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        // 创建bodypart封装正文        MimeBodyPart text = new MimeBodyPart();        text.setContent("hello, hello, liayun<img src='cid:1.jpg'>", "text/html");        // 创建bodypart封装图片        MimeBodyPart image = new MimeBodyPart();        image.setDataHandler(new DataHandler(new FileDataSource("src/1.jpg")));        image.setContentID("1.jpg");        // 创建bodypart封装附件        MimeBodyPart attach = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/1.mp3"));        attach.setDataHandler(dh);        // 只要调用了setFileName方法,它就会自动帮你生成Content-Disposition这个头字段        attach.setFileName(dh.getName());        // 描述数据关系        MimeMultipart content = new MimeMultipart();        content.addBodyPart(text);        content.addBodyPart(image);        content.setSubType("related");        MimeBodyPart mbp = new MimeBodyPart();        mbp.setContent(content);        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(mbp);        mm.addBodyPart(attach);        mm.setSubType("mixed");        message.setContent(mm);        message.saveChanges();        // 将创建好的邮件写入到C盘以文件的形式进行保存        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

运行该程序,我们可以在C盘下看到有生成一个1.eml文件。

中文名的邮件附件的乱码问题

我们中国人编写程序真的很麻烦,每学完一个新的技术,就要考虑中文乱码问题,现在我们就要开始考虑这个问题了。我们就以使用JavaMail API创建包含内嵌图片和附件的复杂邮件为例,来说明创建邮件中的一些中文乱码问题。按照咱中国人的习惯,创建一封邮件时,有可能邮件的主题是中文,邮件的正文也是中文,邮件所带的附件的名字同样也是中文,如下:

public class ComplexMail {    /*     * 世界上最复杂的邮件     */    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("我爱你,那个人");        // 创建bodypart封装正文        MimeBodyPart text = new MimeBodyPart();        text.setContent("我是真的爱你,你知道吗?<img src='cid:1.jpg'>", "text/html");        // 创建bodypart封装图片        MimeBodyPart image = new MimeBodyPart();        image.setDataHandler(new DataHandler(new FileDataSource("src/1.jpg")));        image.setContentID("1.jpg");        // 创建bodypart封装附件        MimeBodyPart attach = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/爱的秘密蓝调口琴曲.mp3"));        attach.setDataHandler(dh);              // 只要调用了setFileName方法,它就会自动帮你生成Content-Disposition这个头字段        attach.setFileName(dh.getName());        // 描述数据关系        MimeMultipart content = new MimeMultipart();        content.addBodyPart(text);        content.addBodyPart(image);        content.setSubType("related");        MimeBodyPart mbp = new MimeBodyPart();        mbp.setContent(content);        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(mbp);        mm.addBodyPart(attach);        mm.setSubType("mixed");        message.setContent(mm);        message.saveChanges();        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

运行该程序,我们可以在C盘下看到有生成一个1.eml文件。如果我们使用Microsoft Outlook这样的客户端工具打开这个文件,会发现:

  • 邮件主题显示正常,没有出现中文乱码问题
  • 邮件正文显示为乱七八糟的东西,出现中文乱码问题
  • 邮件的附件名也显示为乱七八糟的东西,出现中文乱码问题

这时,到底该怎么解决呢?解决代码如下:

public class ComplexMail {    /*     * 世界上最复杂的邮件     */    public static void main(String[] args) throws Exception {        // 创建邮件        Session session = Session.getDefaultInstance(new Properties()); // session代表与邮件服务器的会话        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("我爱你,那个人");        // 创建bodypart封装正文        MimeBodyPart text = new MimeBodyPart();        text.setContent("我是真的爱你,你知道吗?<img src='cid:1.jpg'>", "text/html;charset=UTF-8");        // 创建bodypart封装图片        MimeBodyPart image = new MimeBodyPart();        image.setDataHandler(new DataHandler(new FileDataSource("src/1.jpg")));        image.setContentID("1.jpg");        // 创建bodypart封装附件        MimeBodyPart attach = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/爱的秘密蓝调口琴曲.mp3"));        attach.setDataHandler(dh);        // System.out.println(dh.getName()); // 数据处理器获取附件名时没有中文乱码问题,显示正常        // 只要调用了setFileName方法,它就会自动帮你生成Content-Disposition这个头字段        attach.setFileName(MimeUtility.encodeText(dh.getName())); // 设置附件名的时候出现中文乱码问题了,该怎么解决呢?        // 描述数据关系        MimeMultipart content = new MimeMultipart();        content.addBodyPart(text);        content.addBodyPart(image);        content.setSubType("related");        MimeBodyPart mbp = new MimeBodyPart();        mbp.setContent(content);        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(mbp);        mm.addBodyPart(attach);        mm.setSubType("mixed");        message.setContent(mm);        message.saveChanges();        message.writeTo(new FileOutputStream("c:\\1.eml"));    }}

这样,我们在使用JavaMail API创建不管什么类型的邮件时,所有与中文乱码相关的问题都已解决,大家可以放心大胆地创建邮件了。

使用JavaMail API发送邮件

邮件收发 API 的体系结构:
这里写图片描述
JavaMail API按其功能划分通常可分为如下三大类:

  • 创建和解析邮件内容的API:Message类是创建和解析邮件的核心API,它的实例对象代表一封电子邮件。
  • 发送邮件的API:Transport类是发送邮件的核心API类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如SMTP协议。
  • 接收邮件的API:Store类是接收邮件的核心API类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如POP3协议。

邮件发送 API 的体系结构

JavaMail API中定义了一个java.mail.Transport类,它专门用于执行邮件发送任务,这个类的实例对象封装了某种邮件发送协议的底层实施细节,应用程序调用这个类中的方法就可以把Message对象中封装的邮件数据发送到指定的SMTP服务器。使用JavaMail发送邮件是涉及到的主要API之间的工作关系如图所示:
这里写图片描述
图中的各个类的功能及相互关系如下:

  1. 从Session对象中获得实现了某种邮件发送协议的Transport对象。
  2. 使用Session对象创建Message对象,并调用Message对象的方法封装邮件数据。
  3. 连接指定的SMTP服务器,调用Transport对象中的邮件发送方法发送Message对象中封装的邮件数据。

Session类

mail.jar包中的javax.mail.Session类用于定义整个JavaMail应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,如邮件服务器的主机名、端口号、采用的邮件发送和接收协议等。Session对象根据这些信息构建用于邮件收发的Transport和Store对象,以及为客户端创建Message对象时提供信息支持。下面是Session类中定义的常用方法。

getInstance与getDefaultInstance方法

getInstance和getDefaultInstance是Session类中的静态方法,它们都可用于获得Session类的实例对象。由于Session类的构造函数是私有的,所以,应用程序必须调用getInstance或getDefaultInstance静态方法获得Session类的实例对象。getInstance方法和getDefaultInstance方法各有两种重载形式,它们的语法定义如下:

  • public static Session getInstance(java.util.Properties props)
  • public static Session getInstance(java.util.Properties props, Authenticator authenticator)
  • public static Session getDefaultInstance(java.util.Properties props)
  • public static Session getDefaultInstance(java.util.Properties props, Authenticator authenticator)

getInstance方法与getDefaultInstance方法的区别在于:getDefaultInstance方法返回一个Session对象后,将把这个Session对象安装为缺省的Session对象,以后每次调用getDefaultInstance方法都将返回这个缺省Session对象;而getInstance方法则是每次调用都返回一个新的Session对象。只要掌握了getInstance方法的应用,自然也就掌握了getDefaultInstance方法的应用,所以下面只以getInstance方法为例进行讲解。
两个重载的getInstance方法都接收一个Properties对象作为参数,Properties对象中保存了实例化Session对象所需的应用程序环境信息,以及客户端与邮件服务器建立连接所必须的会话信息。这些信息被称为JavaMail属性,它们的属性名作为Properties对象的关键字进行保存。表中列出了一些常用的JavaMail连接属性,更多的属性可以查看JavaMail规范文档中的附录A部分和各种协议的服务实现程序的有关文档。

JavaMail属性 描述 mail.smtp.host 指定连接的邮件服务器主机名 mail.transport.protocol 指定采用的邮件发送协议 mail.store.protocol 指定采用的邮件接收协议 mail.smtp.auth 指定客户端是否向邮件服务器提交认证

第二个getInstance方法除了接收一个Properties类型的参数外,还接收一个Authenticator对象作为参数。Authenticator主要用于提供用户认证信息,调用第二个getInstance方法创建Session对象时,将把作为第二个参数传入的Authenticator对象注册到该Session对象中。以后,使用这个Session对象的JavaMail客户端程序要向邮件服务器提交认证信息时,将调用该Session对象中注册的Authenticator对象,从中获得用户认证信息后传递给邮件服务器。

邮件发送程序

我们先使用JavaMail API发送一封简单的邮件,步骤为

  • 创建包含邮件服务器的网络连接信息的Session对象。
  • 创建代表邮件内容的Message对象。
  • 创建Transport对象、连接服务器、发送Message、关闭连接。

这样使用JavaMail API发送一封最简单的邮件(纯文本邮件)的代码为:

public class SendMail {    public static void main(String[] args) throws Exception {        Properties prop = new Properties();        prop.setProperty("mail.smtp.host", "smtp.163.com");        prop.setProperty("mail.transport.protocol", "smtp");        prop.setProperty("mail.smtp.auth", "true");        Session session = Session.getInstance(prop); // 创建出与指定邮件服务器会话的session        /*         * 为了看清javamail这套API到底是如何向服务器发邮件的,可以把session的Debug开关打开,         * 把这个调试开关打开,javamail这套API会把它与服务器的交互过程打印在命令行窗口         */        session.setDebug(true);        Message message = createMessage(session);        Transport ts = session.getTransport();        ts.connect("yerenyuan10001", "邮箱登录密码"); // 连接上邮件服务器,其内部会自动帮你进行base64编码        ts.sendMessage(message, message.getAllRecipients()); // 向谁发送一封邮件        ts.close(); // 断开与服务器的连接    }    private static Message createMessage(Session session) throws AddressException, MessagingException, UnsupportedEncodingException {        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("love");        message.setContent("hello hello liayun", "text/html");        message.saveChanges();        return message;    }}

提示:创建出包含邮件服务器的网络连接信息的Session对象之后,为了看清JavaMail这套API到底是如何向邮件服务器发送邮件的,可以把session的Debug开关打开,把这个调试开关打开后,JavaMail这套API会把它与邮件服务器的交互过程打印在Eclipse的控制台上。
运行以上程序,然后登陆到i_beautifulman@sina.com邮箱当中,就可以收取到由yerenyuan10001@163.com发送的Email了,如下图所示:
这里写图片描述
接着我们使用JavaMail API发送一封复杂邮件,如下:

public class SendMail {    public static void main(String[] args) throws Exception {        Properties prop = new Properties();        prop.setProperty("mail.smtp.host", "smtp.163.com");        prop.setProperty("mail.transport.protocol", "smtp");        prop.setProperty("mail.smtp.auth", "true");        Session session = Session.getInstance(prop); // 创建出与指定邮件服务器会话的session        /*         * 为了看清javamail这套API到底是如何向服务器发邮件的,可以把session的Debug开关打开,         * 把这个调试开关打开,javamail这套API会把它与服务器的交互过程打印在命令行窗口         */        session.setDebug(true);        Message message = createMessage(session);        Transport ts = session.getTransport();        ts.connect("yerenyuan10001", "邮箱登录密码"); // 连接上邮件服务器,其内部会自动帮你进行base64编码        ts.sendMessage(message, message.getAllRecipients()); // 向谁发送一封邮件        ts.close(); // 断开与服务器的连接    }    private static Message createMessage(Session session) throws AddressException, MessagingException, UnsupportedEncodingException {        // 创建邮件        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress("yerenyuan10001@163.com"));        message.setRecipient(Message.RecipientType.TO, new InternetAddress("i_beautifulman@sina.com"));        message.setSubject("我爱你,那个人");        // 创建bodypart封装正文        MimeBodyPart text = new MimeBodyPart();        text.setContent("我是真的爱你,你知道吗?<img src='cid:1.jpg'>", "text/html;charset=UTF-8");        // 创建bodypart封装图片        MimeBodyPart image = new MimeBodyPart();        image.setDataHandler(new DataHandler(new FileDataSource("src/1.jpg")));        image.setContentID("1.jpg");        // 创建bodypart封装附件        MimeBodyPart attach = new MimeBodyPart();        DataHandler dh = new DataHandler(new FileDataSource("src/爱的秘密蓝调口琴曲.mp3"));        attach.setDataHandler(dh);        // System.out.println(dh.getName()); // 数据处理器获取附件名时没有中文乱码问题,显示正常        // 只要调用了setFileName方法,它就会自动帮你生成Content-Disposition这个头字段        attach.setFileName(MimeUtility.encodeText(dh.getName())); // 设置附件名的时候出现中文乱码问题了,该怎么解决呢?        // 描述数据关系        MimeMultipart content = new MimeMultipart();        content.addBodyPart(text);        content.addBodyPart(image);        content.setSubType("related");        MimeBodyPart mbp = new MimeBodyPart();        mbp.setContent(content);        MimeMultipart mm = new MimeMultipart();        mm.addBodyPart(mbp);        mm.addBodyPart(attach);        mm.setSubType("mixed");        message.setContent(mm);        message.saveChanges();        return message;    }}

运行以上程序,然后登陆到i_beautifulman@sina.com邮箱当中,就可以收取到由yerenyuan10001@163.com发送的Email了,如下图所示:
这里写图片描述
将附件爱的秘密蓝调口琴曲.mp3下载下来,并且能成功播放。

0 0
原创粉丝点击