1、电子邮件概述
1.1 概述
电子邮件是互联网上使用最多和最受欢迎的一种应用。
电子邮件把邮件发送到收件人使用的邮件服务器,并放在其中的收件人邮箱中,收件人可以在自己方便时上网到自己使用的邮件服务器进行读取。
发送邮件:SMTP(Simple Mail Transfer Protocol:简单邮件传送协议)协议
接收协议:POP3协议(邮局协议Post Office Protocol
第3个版本)
1.2 MIME
SMTP协议的缺点:
- 不能传送可执行文件或其他的二进制对象;
- 限于传送7位的ASCII码。
- SMTP服务器会拒绝超过一定长度的邮件
- 某些SMTP的实现并没有完全按照SMTP的互联网标准。常见的问题如下:
- 回车、换行的删除和增加;
- 超过76个字符时的处理:截断或自动换行;
- 后面多余空格的删除;
- 将制表符转换为若干个空格。
基于上述情况提出了通用互联网邮件扩充MIME
。MIME的意图是继续使用原来的邮件格式,但是增加了邮件主体的结构,并定义了传送非ASCII码的编码规则。MIME邮件可以在现有的电子邮件程序和协议下传送。即附件。
MIME主要包括以下三部分内容:
- ① 5个新的邮件首部字段,它们可以包含在原来的邮件首部中。这些字段提供了有关邮件主体的信息;
- MIME-Version:标志MIME版本号。
- Cntext-Dscription:可读字符串,说明此邮件主题是否是图像、音频或视频;
- Context-Id:邮件的唯一标识符;
- Context-Transfer-Encoding:在传送时邮件的主题是如何编码的;
- Context-Type:邮件主体的数据类型和子类型。
- 定义了许多邮件内容的格式,对多媒体电子邮件的表示方法进行了标准化;
- 定义了传送编码,可对任何内容格式进行转换,而不会被邮件系统改变。
为了适应任意数据类型和表示,每个MIME报文包含告知收件人数据类型和使用编码的信息。
2、主要构件
一个电子邮件系统应该具有如下所示的三个主要组成构件:
- 用户代理
- 邮件服务器
- 邮件发送协议和邮件接收协议
上图的步骤:
- 发件人调用计算机中的用户代理撰写和编辑要发送的邮件;
- 发件人点击发送后,发送邮件的工作就全盘交由用户代理来完成。用户代理使用SMTP协议发送给发送方邮件服务器,用户代理充当SMTP客户,而发送方邮件服务器充当SMTP服务器。
- SMTP服务器收到用户代理发来的邮件后,就把邮件存放在邮件缓存队列中,等待发送到接收方的邮件服务器。等待的时间长短取决于邮件服务器的处理能力和队列中待发送的邮件的数量。
- 发送方邮件服务器的SMTP客户与接收方邮件服务器的SMTP服务器建立TCP连接,然后就把邮件缓存队列中的邮件依次发送出去;
- 运行在接收方的SMTP邮件服务器中的SMTP服务器进程接收到邮件后,就把邮件放入收件人的用户邮箱中,等待收件人读取;
- 收件人收件时,运行计算机中的用户代理,使用POP3(或IMAP)协议读取发送给自己的邮件。
用户代理UA:即是用户与电子邮件系统的接口,在大多数情况下它就是运行在用户电脑中的一个程序。因此用户代理又称为电子邮件客户端软件。用户代理至少具有以下4个功能:
- 撰写:给用户提供编辑信件的功能;
- 显示:能方便地在计算机屏幕上显示出来信(包括来信附件上的声音和图像);
- 处理:包括发送和接收邮件;
- 通信:发信人在撰写完邮件之后,要利用邮件发送协议发送到用户所使用的邮件服务器。收件人在接收邮件时,要使用邮件读取协议从本地邮件服务器接收文件。
3、代码实现
需要的JAR包
- JavaMail:sun公司(先被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议(SMTP、POP3、MIME等)。使用JavaMail编写邮件时只需调用对应的API类就行。
- JAF:
核心类包括四个:
- Session:定义整个程序所需的环境信息,比如主机名、端口号、采用的发送和接收邮件的协议
- Message:表示一封电子邮件
- Transport:发送邮件
- Store:接收邮件
3.1 简单邮件实现
简单邮件:没有附件和图片,即纯文本文件。
- 设置要发送的邮件服务器;
- 邮件发送协议;
- 需要验证用户名和密码
Properties prop = new Properties();
prop.put("mail.host","smtp.qq.com"); //设置QQ邮件服务器
prop.put("mail.transport.protocol","smtp"); //设置邮件发送协议
prop.put("mail.smtp.auth","true"); //需要验证用户名和密码
使用QQ邮箱,需要设置SSL加密,加上如下所示的代码:
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable","true");
prop.put("mail.smtp.ssl.socketFactory",sf);
使用JavaMail发送邮件的步骤:
-
创建定义整个应用程序所需要的环境信息的 Session 对象;
// 获取默认session对象。QQ特有的,其它邮箱不需要使用 Session session = Session.getDefaultInstance(prop,new Authenticator(){ public PasswordAuthentication getPasswordAuthentication() { //发件人邮件用户名、密码 return new PasswordAuthentication("3061628106@qq.com", "xxxxxxxxxxxxxx"); } });
【注】使用的密码如下所示获取
//开启session的debug模式,可以查看程序发送Email的运行状态 session.setDebug(true);
-
通过Session对象获取 Transport对象;
Transport transport = session.getTransport();
-
使用邮箱的用户名和授权码连上邮件服务器;
transport.connect("smtp.qq.com","3061628106@qq.com","ladwrtyxiugcdgfh");
-
创建邮件;
//Message是一个抽象类,需要使用其子类(实现了抽象方法的类)来创建邮件信息 MimeMessage message = new MimeMessage(session); // 1.设置发送邮件的人 message.setFrom(new InternetAddress("3061628106@qq.com")); // 2.设置收件人 message.addRecipient(Message.RecipientType.TO, new InternetAddress("3061628106@qq.com")); // 3.设置发送的主题 message.setSubject("这是Java邮件发送的测试"); // 4.设置需要发送的内容 message.setText("Hello, message","utf-8");
-
发送邮件。
//message.getAllRecipients():获取所有要发送的人 transport.sendMessage(message,message.getAllRecipients());
-
关闭资源
transport.close();
3.2 发送一封HTML邮件
步骤与发送简单邮件的步骤一样,只需要在发送的内容后面加上"text/html"
-
创建定义整个应用程序所需要的环境信息的 Session 对象;
-
通过Session对象获取 Transport对象;
-
使用邮箱的用户名和授权码连上邮件服务器;
-
创建邮件;
// 4.设置需要发送的内容 message.setText("<h1 style='color: blue'>Hello, message<h1>","text/html;utf-8");
-
发送邮件。
-
关闭资源
3.3 发送一封带有附件的邮件
需要使用如下两个类:
- MimeBodyPart :表示的是一个MIME消息,和MimeMessage一样都是继承Part接口;
- MimeMultipart:是抽象类Multipart的实现子类,用于组合多个MIME消息。一个MimeMulitpart对象可以包含多个代表MIME消息的MimeBodyPart对象。
步骤:
-
创建定义整个应用程序所需要的环境信息的 Session 对象;
-
通过Session对象获取 Transport对象;
-
使用邮箱的用户名和授权码连上邮件服务器;
-
创建邮件(这个地方与纯文本文件不同)
//1.Message是一个抽象类,需要使用其子类(实现了抽象方法的类)来创建邮件信息 MimeMessage message = new MimeMessage(session); //2.设置发送邮件的人 message.setFrom(new InternetAddress("3061628106@qq.com")); //3.设置收件人 message.addRecipient(Message.RecipientType.TO, new InternetAddress("3061628106@qq.com")); //4.设置发送的主题 message.setSubject("这是Java邮件发送的测试"); //5.准备邮件数据 //需求:在文本中内嵌入一张图片 //准备图片数据 MimeBodyPart image = new MimeBodyPart(); //将图片进行数据处理 DataHandler handler = new DataHandler(new FileDataSource("D:\\JetBrains\\WorkSpace01\\Project01\\file_module\\src\\test.jpg")); //在主体Body中放入图片数据 image.setDataHandler(handler); //给图片设置一个id,一遍后面内嵌中使用 image.setContentID("myTest.jpg"); //准备正文数据 MimeBodyPart text = new MimeBodyPart(); text.setContent("这是带有图片的文本邮件<img src='cid:myTest.jpg'>","text/html;charset=utf-8"); //描述数据关系 MimeMultipart multipart = new MimeMultipart(); multipart.addBodyPart(text); multipart.addBodyPart(image); multipart.setSubType("related"); //设置到消息中,并保存修改 message.setContent(multipart); //将编辑好的邮件内容放到消息中去 message.saveChanges(); //保存修改
-
发送邮件
-
关闭资源
发送带有文件的邮件
在第4步创建邮件中的准备邮件数据,添加文件如下所示。
// 附件部分
messageBodyPart = new MimeBodyPart();
String filename = "file.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);