Java程序中使用JavaMail发送带图片和附件的邮件
作者:haolloyin 发布时间:2022-07-02 17:00:33
我们常常在邮件中添加附件,以达到传输较大文件的目的。而上一篇文章只是将本机的一张图片内嵌到邮件的 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 对象指向的资源文件。
程序代码:
这个不同点在下面代码中会用橙色背景强调指出,代码如下:
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 文件,双击打开,如下图:
看看上面用 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 协议对邮件结构组织的规范格式。


猜你喜欢
- 今天一直在绞尽脑汁的寻找解决两个字符之间的内容如何输出的问题,刚开始就使用了万能的正则表达式;但是不知哪里的原因自己的数据一直出不来,觉得应
- 众所周知,当你点击一个超链接进行跳转时,WebView会自动将当前地址作为Referer(引荐)发给服务器,因此很多服务器端程序通过是否包含
- 题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。程序分析:请抓住分子与分母的变化规
- C语言字符串大小比较#include <stdio.h>#include <string.h>int fun(cha
- 前言在移动互联网浪潮中,联网APP已经把单机拍死在沙滩上,很多公司都希望自家应用能够有一套帐号系统,可是许多用户却并不一定买账:
- 最近在做一个需求:从其他系统的ftp目录下载存储图片url的文件,然后读取文件中的url地址,根据地址下载图片后按天压缩成一个包,平均一个地
- 这篇文章主要介绍了Spring整合MyBatis图示过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 在文章中,我们将对输入到机器学习模型中的数据集进行预处理。这里我们将对一个硬币数据集进行预处理,以便以后在监督学习模型中进行训练。在机器学习
- IEnumerable、ICollection、IList、List之间的区别,本文分别分析了它的实现源码,从而总结出了它们之间的关系和不同
- 本文实例为大家分享了Springboot整合pagehelper分页展示的具体代码,供大家参考,具体内容如下一、添加依赖查找maven中pa
- Java.lang 中自带的注解@Override:表示当前的方法定义将覆盖基类的方法。如果你不小心拼写错误,或者方法签名被错误拼写的时候,
- 一、简介我们在线程编程的时候往往会涉及到线程的通信,通过信号的接受来进行线程是否阻塞的操作。AutoResetEvent 允许线程通过发信号
- 1.object.toString()方法这种方法要注意的是object不能为null,否则会报NullPointException,一般别
- 静态方法代理:public delegate void DoGreeting(string name);class Program 
- Idea运行单个main方法,不编译整个工程直接上图1、选择main方法类右键->create ‘类名.main&
- 本文实例为大家分享了Java实现简单邮件发送的具体代码,供大家参考,具体内容如下需要的jar包:activation-1.1.1.jarma
- 本文实例为大家分享了C#实现套接字发送接收数据的具体代码,供大家参考,具体内容如下服务端namespace TestServer{ &nbs
- 一、Statementimport java.sql.*;public class TestJDBC { public stati
- 今天来写一个通用的筛选栏的实现,也是因为之前项目中要好多地方用到筛选栏这么个东西,所以为了之后用起来比较方便,就简单的做了一些封装.废话不多
- 一、概述运行时变更就是设备在运行时发生变化(例如屏幕旋转、键盘可用性及语言)。发生这些变化,Android会重启Activity,这时就需要