eml格式说明

eml解析
1.eml格式说明
eml文件是遵循遵循RFC822及其后续扩展的格式文件,RFC中定义的邮件结构包括两个部分,即邮件头和邮件体,两者由一个空行隔开。
邮件头包括几个部分:主题、创建者、收信人以及邮件创建日期,邮件体内容类型、邮件体内容传输编码方式等。邮件体部分包括正文和附件,结构较复杂。

2.邮件头
邮件头中不允许出现空行,
在邮件头中,有很多从RFC 822沿用的域名,MIME也增加了一些。常见的标准域名和含义如下:
域名 含义 添加者
Received 传输路径 各级邮件服务器
Return-Path 回复地址 目标邮件服务器
Delivered-To 发送地址 目标邮件服务器
Reply-To 回复地址 邮件的创建者
From 发件人地址 邮件的创建者
To 收件人地址 邮件的创建者
Cc 抄送地址 邮件的创建者
Bcc 暗送地址 邮件的创建者
Date 日期和时间 邮件的创建者
Subject 主题 邮件的创建者
Message-ID 消息ID 邮件的创建者
MIME-Version MIME版本 邮件的创建者
Content-Type 内容的类型 邮件的创建者
Content-Transfer-Encoding 内容的传输编码方式 邮件的创建者

3.邮件体
Eml文件中的邮件体部分解析时要根据其Content-Type类型决定具体访问方法。Content-Type一般包括文本的类型、文本使用的字符集等,文本为复合类型时还包括分隔不同部分的分界字符串(boundary)。Content-Type都是“主类型/子类型”的格式。
RFC2046定义Content-Type顶层有5种离散类型和两种复合类型。离散类型是text(文本信息),image(图像信息),audio(音频信息),video(视频信息),application(其它信息)。复合类型是multipart(多部分信息)和message(压缩信息),顶层类型又有其子类型。正常邮件中正文文本多是text类型,其它类型大多作为附件方式存在。由于邮件中可能多种类型并存,且不同复合类型会相互嵌套。
(1)当邮件体中只出现某种离散的顶层类型时。比如邮件的Content—Type类型为Text/plain,Text是顶层类型,说明邮件体为文本类型,plain是Text的一种子类型:纯文本类型。只需要读取邮件头部分的Content—transfer~Encoding字段,来判断该邮件体部分(可以根据邮件头和邮件体部分以空行分开这个特点来提取出邮件体)是否采用了某种编码方式。如果没有编码,可以直接返回前面已经得到字符串,否则调用需要的编码程序,将解码后的字符串返回。
(2)当邮件中出现复合的顶层类型时,情况就比较复杂,下面以较常见的Multipart为例进行说明。在Mtdtipart类型中,有两个常见子类Mixed,Alternative。Mixed类型说明文本内有多个部分,并且各部分之间是有次序的,那么在分析邮件体的时候,必须考虑到其内容的顺序,按其原先出现的顺序来提取出邮件体内容。而Alternative说明文本是以多种类型出现的相同内容,接收者可以根据用户的需要来提取所需要的类型或者默认将所有的类型均显示出来。邮件体中各个部分之间以boundary分隔。
±------------------------ multipart/mixed ----------------------------+
| |
| ±---------------- multipart/related ------------------+ |
| | | |
| | ±---- multipart/alternative ------+ ±---------+ | ±-----+ |
| | | | | 内嵌资源 | | | 附件 | |
| | | ±-----------+ ±-----------+ | ±---------+ | ±-----+ |
| | | | 纯文本正文 | | 超文本正文 | | | |
| | | ±-----------+ ±-----------+ | ±---------+ | ±-----+ |
| | | | | 内嵌资源 | | | 附件 | |
| | ±---------------------------------+ ±---------+ | ±-----+ |
| | | |
| ±-----------------------------------------------------+ |
| |
±---------------------------------------------------------------------+

可以看出,如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。什么是“至少”?举个例子说,如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。
这些复合类型又是可以嵌套使用的,比如说一个带有附件的邮件,同时有html与text两种格式的正文,则邮件的结构是:
  Content-Type: multipart/mixed
  部分一:
  Content Type : multipart/alternative:
  Text 正文;
  Html 格式的正文 
  部分二:
  附件
邮件结束符;

multipart诸类型的共同特征是,在段头指定“boundary”参数字符串,段体内的每个子段以此串定界。所有的子段都以“–”+boundary行开始,父段则以“–”+boundary+“–”行结束。段与段之间也以空行分隔。在邮件体是multipart类型的情况下,邮件体的开始部分(第一个“–”+boundary行之前)可以有一些附加的文本行,相当于注释,解码时应忽略。段间也可以有一些附加的文本行,不会显示出来。

4.编码
Content-Transfer-Encoding 它表示了这个部分文档的编码方式。只有识别了这个说明,才能用正确的解码方式实现对其解码。
Content-Transfer-Encoding共有Base64, Quoted-printable, 7bit, 8bit, Binary等几种。
其中7bit是缺省的编码方式。电子邮件源码最初设计为全部是可打印的ASCII码的形式。
(1)7bit, 8bit 无需解码
(2)Binary方式只具有象征意义,而没有任何实用价值.
(3)Base64编码
Base64编码适用于不可读的二进制文件,如中文文档等。编码方法是将原始字符串每三个字符放入一个24位缓冲区并等分为4份,高位在先,根据每6位所对应的数字的大小,用A~z,a~Z,0~9,+,供64个字符重新表示。若编码后的位数不是4的整数倍,在最后以“=”来填充。
(4)Quoted-printable编码
QP编码是一种使用可打印的ASCII字符 (如字母、数字与"=")表示各种编码格式下的字符。其方法是将一个8bit的字符表示成两个16进制数,并在前面加一个“=”,共三个ASCII字符。

5.解析程序思路
先判断邮件体中只出现某种离散的顶层类型,还是邮件中出现复合的顶层类型。
(1) 只出现某种离散的顶层类型时
一般这样正文只有文本,先从文件最开始出开始循环读,一次读一行,然后
判断每很是否有读出发送人,时间,主题,编码方式等信息(用段头来匹配)。
再找邮件体(就是找第一个出现的空行),从这个空行到文件结束都是正文,读取出来,再用相应的解码的算法解码即可。
(2) 邮件中出现复合的顶层类型时
先从文件最开始出开始循环读,一次读一行,然后判断每行是否有读出发
送人,时间,主题,编码方式,boundary(取出其分隔符)等信息(用段头来匹配),再利用附件和正文的分隔符,匹配出正文和附件,然后解码即可。

Java可以使用JavaMail API来生成EML格式的电子邮件。以下是生成EML格式邮件的基本步骤: 1. 添加JavaMail和相关依赖项的库文件到项目中。 2. 创建一个JavaMail会话对象,并设置SMTP服务器和SMTP服务器端口。 ```java Properties props = new Properties(); props.setProperty("mail.smtp.host", "your_smtp_server"); props.setProperty("mail.smtp.port", "your_smtp_port"); Session session = Session.getInstance(props, null); ``` 3. 创建一个MimeMessage对象,并设置发送者、收件人、主题、正文和其他相关信息。 ```java MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress("sender@example.com")); message.setRecipient(Message.RecipientType.TO, new InternetAddress("recipient@example.com")); message.setSubject("Test Email"); message.setText("This is a test email."); message.setHeader("X-Mailer", "JavaMail"); message.setSentDate(new Date()); ``` 4. 将MimeMessage对象保存为EML格式文件。 ```java message.writeTo(new FileOutputStream(new File("test.eml"))); ``` 完整的Java代码示例如下: ```java import java.io.File; import java.io.FileOutputStream; import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; public class EmlGenerator { public static void main(String[] args) throws Exception { Properties props = new Properties(); props.setProperty("mail.smtp.host", "your_smtp_server"); props.setProperty("mail.smtp.port", "your_smtp_port"); Session session = Session.getInstance(props, null); MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress("sender@example.com")); message.setRecipient(Message.RecipientType.TO, new InternetAddress("recipient@example.com")); message.setSubject("Test Email"); message.setText("This is a test email."); message.setHeader("X-Mailer", "JavaMail"); message.setSentDate(new Date()); message.writeTo(new FileOutputStream(new File("test.eml"))); } } ``` 执行以上代码后,将会在项目根目录下生成一个名为test.emlEML格式文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值