Java程序中使用JavaMail发送带图片和附件的邮件

 更新时间:2015年11月24日 17:51:16   作者:haolloyin  
这篇文章主要介绍了Java程序中使用JavaMail发送带图片和附件的邮件,JavaMail是专门用来处理邮件的Java API,需要的朋友可以参考下

我们常常在邮件中添加附件,以达到传输较大文件的目的。而上一篇文章只是将本机的一张图片内嵌到邮件的 HTML 格式的正文当中,这样的邮件显得不够丰富多彩。我们想要一封正文部分图文并茂,而游客附带若干附件的邮件。
下面是代码结构中3个重要的方法:

  1. MimeBodyPart createAttachment(String fileName) 方法用于创建附件并返回;
  2. MimeBodyPart createContent(String body, String fileName) 方法用于创建正文部分并返回;
  3. MimeMessage createMessage(Session session) 方法用于调用上面的两个方法生成邮件。

其实,创建一个内含附件的邮件与上一篇文章中创建正文中包含图片的邮件的原理,甚至代码都几乎相同。也就是使用 JAF 框架中的 FileDataSource 类和 DataHandler 类来获得给定路径的资源文件,JAF 框架中的这两个类共同协作可以获知文件所属的 MIME 类型,它们会正确地添加到邮件组织结构中的对应消息头中。

不同的是:
在 HTML 格式的正文中内含图片是使用 MimeBody.setContentID() 方法设置对应的资源文件的唯一标识符,即 MIME 协议对于邮件的结构组织格式中的 Content-ID 头字段;
而在 MIME 邮件中添加附件是使用 MimeBodyPart.setFileName() 方法来关联 FileSourceData 对象指向的资源文件。
程序代码:
这个不同点在下面代码中会用橙色背景强调指出,代码如下:

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 to = "test_hao@sina.cn"; 
    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 文件,双击打开,如下图:

20151124174905292.png (664×256)

20151124174934256.png (457×468)

看看上面用 Outlook 打开生成的文件,在附件栏里面就有一个 .java 源文件和一首 MP3 文件了。
打开邮件的原始内容:
查看生成的邮件的原始内容,点击“文件”、“属性”、“邮件来源”或者使用 EditPlus 、UltraEdit 等文本编辑器直接打开也行,下面是原始内容:

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 协议对邮件结构组织的规范格式。

相关文章

  • Java原子变量类常见问题解决

    Java原子变量类常见问题解决

    这篇文章主要介绍了Java原子变量类常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Spring Boot 集成Mybatis实现主从(多数据源)分离方案示例

    Spring Boot 集成Mybatis实现主从(多数据源)分离方案示例

    本篇文章主要介绍了Spring Boot 集成Mybatis实现主从(多数据源)分离方案实例,具有一定的参考价值,有兴趣的可以了解一下。
    2017-03-03
  • 一文详解Java中的反射与new创建对象

    一文详解Java中的反射与new创建对象

    Java中的反射(Reflection)和使用new关键字创建对象是两种不同的对象创建方式,各有优缺点和适用场景,本文小编给大家详细介绍了Java中的反射与new创建对象,感兴趣的小伙伴跟着小编一起来看看吧
    2024-07-07
  • 使用@ConditionalOnProperty控制是否加载的操作

    使用@ConditionalOnProperty控制是否加载的操作

    这篇文章主要介绍了使用@ConditionalOnProperty控制是否加载的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Springboot的spring-boot-maven-plugin导入失败的解决方案

    Springboot的spring-boot-maven-plugin导入失败的解决方案

    这篇文章主要介绍了Springboot的spring-boot-maven-plugin导入失败的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java面向对象设计原则之迪米特法则介绍

    Java面向对象设计原则之迪米特法则介绍

    迪米特法则解决类与类之间耦合度问题,如果类A调用了B类的某一个方法,则这两个类就形成了一种紧耦合的方式,当B类这个方法发生变化时,一定会影响A类的执行结果。迪米特法则要求每一个类尽可能少的与其他类发生关系
    2023-02-02
  • 基于Java回顾之I/O的使用详解

    基于Java回顾之I/O的使用详解

    我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容
    2013-05-05
  • SpringBootWeb 入门了解 Swagger 的具体使用

    SpringBootWeb 入门了解 Swagger 的具体使用

    这篇文章主要介绍了SpringBootWeb 入门了解 Swagger 的具体使用,Swagger 框架可以根据已经实现的方法或者类,通过页面的方式直观清晰的查看或者进行测试该方法,需要的朋友可以参考下
    2024-08-08
  • Java中SpringCloud的五大组件详解

    Java中SpringCloud的五大组件详解

    这篇文章主要介绍了Java中SpringCloud的五大组件详解,Spring cloud是一个基于Spring Boot实现的服务治理工具包,在微服务架构中用于管理和协调服务,需要的朋友可以参考下
    2023-07-07
  • 基于rabbitmq延迟插件实现分布式延迟任务

    基于rabbitmq延迟插件实现分布式延迟任务

    这篇文章主要介绍了基于rabbitmq延迟插件实现分布式延迟任务,今天我们讲解延迟队列的实现方式,而延迟队列有很多种实现方式,今天就每种实现方式给大家大概介绍下,感兴趣的朋友一起看看吧
    2022-01-01

最新评论