2.1 相关邮件协议 邮件的传送要依赖于具体的传输协议,主要有:SMTP、POP3、MIME。 (1)SMTP:简单邮件传输协议,它是一组用于由源地址到目的地传送邮件的规则,或者说是由它来控制信件传输的一种中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转邮件时找到下一个目的地。通过SMTP协议所指定的服务器,我们就可以把Email寄到收信人的服务器上了,整个过程只需要几分钟。SMTP的开发最初是为了在封闭的网络中传送相对来说不太重要的简短信件,而不是为了在互联网中传送重要而敏感的信息,因此最初通过SMTP传输信件时 ,安全性不高。 (2)POP:邮局协议[5],当前的版本为3,也称作POP3。POP是一种允许用户从邮件服务器收发邮件的协议,它有两种版本,即POP2和POP3,都具有简单的电子邮件存储转发功能。POP2和POP3本质上类似,都属于离线式工作协议,但是由于使用了不通的协议端口,两者并不兼容。与SMTP协议相结合,POP3是目前最常用的电子邮件服务协议。在离线工作方式下,用户收发邮件时,首先通过POP3客户程序登录到支持POP3协议的邮件服务器,然后发送邮件及附件;接着,邮件服务器为该用户收存的邮件传送给POP3客户程序,并将这些邮件从服务器上删除;最后,邮件服务器将用户提交的发送邮件,转发到运行SMTP协议的计算机中,通过它实现邮件的最终发送。在为用户从邮件服务器收取邮件时,POP3是以该用户当前存储在服务器上全部邮件为对象进行操作的,并一次性将它们下载到用户端计算机中。一旦客户的邮件下载完毕,邮件服务器对这些邮件的暂存托管即告完毕。使用POP3,用户不能对他们贮存在邮件服务器上的邮件进行部分传输,离线工作方式适合那些从固定计算机上收发邮件的用户使用。 (3)MIME: 多用途网际邮件扩充协议,是最初的互联网电子邮件协议的一个扩展,说明了如何安排消息格式使消息在不同的邮件系统内进行交换。MIME的格式灵活,使人们能使用这一协议在互联网上交换不同类型的数据文件:音频,视频,图像,应用软件和其他类型的文件,也包括在最初的协议—简单邮件传送协议(SMTP)中的ASCII文本。 (4)IMAP:IMAP使用在接收信息的高级协议,目前版本为第4版,所以也被称为IMAP4。需要注意的是在使用IMAP时,邮件服务器必须支持该协议。从这个方面讲,我们并不能完全使用IMAP来替代POP,不能期待IMAP在任何地方都被支持。假如邮件服务器支持IMAP,那么我们的邮件程序将能够具有以下被IMAP所支持的特性[6]:每个用户在服务器上可具有多个目录,这些目录能在多个用户之间共享。其与POP相比高级之处显而易见,但是在尝试采取IMAP时,我们认识到它并不是十分完美的。由于IMAP需要从其它服务器上接收新信息,将这些信息递送给用户,维护每个用户的多个目录,这都为邮件服务器带来了高负载。并且IMAP与POP的一个不同之处是POP用户在接收邮件时将从邮件服务器上下载邮件,而IMAP允许用户直接访问邮件目录,所以在邮件服务器进行备份作业时,由于每个长期使用此邮件系统的用户所用的邮件目录会占有很大的空间,这将直接导致邮件服务器上磁盘空间暴涨。 (5)NNTP和其它的第三方协议:正因为JavaMail API在设计时考虑到与第三方协议实现提供商之间的分离,故我们可以很容易的添加一些第三方协议。SUN维护着一个第三方协议实现提供商的列表:http://java.sun.com/products/javamail/Third_Party.html,通过此列表我们可以找到所需要的而又不被SUN提供支持的第三方协议:比如NNTP这个新闻组协议和S/MIME这个安全的MIME协议。 2.2JavaMail API 2.2.1 JavaMail API简介 JavaMail API是SUN为Java开发者提供对电子邮件处理的延伸,能用于读取、编写和发送电子消息的包(标准扩展)。为管理电子邮件提供了统一的应用编程接口,它可以处理各种e-mail格式(包括IMAP、POP、SMTP以及MIME)和其他Internet相关的讯息通信协定。 用户可使用这种包创建邮件用户代理(Mail User Agent,MUA)类型的程序,它类似于Foxmail、Eudora以及Miceosoft Outlook这些邮件程序。其主要目的不是像发送邮件或其他邮件传输代理(Mail TransferAgent,MTA)类型的程序那样用于传输、发送和转发消息[7]。换句话说,用户可以与MUA类型的程序交互,以阅读和撰写电子邮件。MUA依靠MTA处理实际的发送任务。 2.2.2 JavaMail API核心类 (1)Session:Session类定义了基本的邮件会话。就像Http会话那样,我们进行收发邮件的工作都是基于这个会话的。Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。
从上面的两个例子中不难发现,getDefaultInstance()和getInstance()方法的第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权。在对mail server进行访问的过程中使用共享的Session是足够的,即使是工作在多个用户邮箱的模式下也不例外。 (2)Message:一旦获得Session对象,就可以继续创建要发送的信息,在这里SUN提供了Message类型来帮助开发者完成这项工作。由于Message是一个抽象类,大多数情况下,我们使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型和头的电子邮件信息。 信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用。为了建立一个MimeMessage对象,我们必须将Session对象作为MimeMessage构造方法的参数传入: MimeMessagemessage = new MimeMessage(session); 注意:对于MimeMessage类来讲存在着多种构造方法,比如使用输入流作为参数的构造方法。 在建立了MimeMessage对象后,我们需要设置它的各个part,对于MimeMessage类来说,这些part就是MimePart接口。最基本的信息内容设置方法就是通过表示信息内容和MIME类型的参数调用setContent()方法:message.setContent("Hello","text/plain")[9];然而,如果我们所使用的MimeMessage中信息内容是文本的话,我们便可以直接使用setText()方法来方便的设置文本内容。message.setText("Hello");前面所讲的两种方法,对于文本信息,后者更为合适。而对于其它的一些信息类型,比如HTML信息,则要使用前者。使用setSubject()方法对邮件设置邮件主题:message.setSubject("First"); (3)Address:到这里,我们已经建立了Session和Message,像Message一样,Address类也是一个抽象类,所以我们将使用javax.mail.internet.InternetAddress这个子类。 本文在这里所讲的邮件地址类是为了设置邮件信息的发信人和收信人而准备的,在建立了邮件地址类后,我们通过message的setFrom()和setReplyTo()两种方法设置邮件的发信人: message.setFrom(address); message.setReplyTo(address); 若在邮件中存在多个发信人地址,我们可用addForm()方法增加发信人: Address address[]= ...; message.addFrom(address); 为了设置收信人,我们使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量来区分收信人的类型: message.addRecipient(type,address) 下面是Message.RecipientType的三个常量: JavaMail API并没有提供检查邮件地址有效性的机制。当然我们可以自己完成这个功能:验证邮件地址的字符是否按照RFC822规定的格式书写或者通过DNS服务器上的MX记录验证等。 (4)Authenticator:JavaMail API也可以利用Authenticator通过用户名和密码访问受保护的资源。对于JavaMail API来说,这些资源就是邮件服务器。JavaMailAuthenticator在javax.mail包中,要使用Authenticator,先创建一个抽象类的子类,并从getPasswordAuthentication()方法中返回PassaordAuthentication实例。创建完成后,必须向Session注册Authenticator。然后,在需要认证的时候,就会通知Authenticator。 (5)Transport:像java.net类那样,JavaMail API通过使用授权者类(Authenticator)以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指邮件服务器。在javax.mail包中可以找到这个JavaMail的授权者类(Authenticator)。 在使用Authenticator这个抽象类时,我们必须采用继承该抽象类的方式,并且该继承类必须具有返回PasswordAuthentication对象(用于存储认证时要用到的用户名、密码)getPasswordAuthentication()方法。并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。 下面代码片断中的MyAuthenticator就是一个Authenticator的子类 (6)Folder和Store:Store类实现特定邮件协议上的读、写、监视、查找等操作。通过javax.mail.Store类可以访问javax.mail.Folder类。 Folder类用于分级组织邮件,并提供javax.mail.Message格式访问e-mail的能力。 2.3.3 JavaMail API的应用 (1)阅读电子邮件 对于阅读邮件来说,首先要获取一个会话,然后获取并连接到一个相应的用于您的收件箱的存储上,接着打开相应的文件夹,再获取消息。同时,不要忘记了操作完成后关闭连接。 步骤如下: ① 创建一个Properties对象,Session对象通过Properties 对象来接受选项,在这种情况下,没有选项,但仍然需要Properties 对象。 ② 创建Session 对象,并不直接对Session 实例化,而是通过调用getDefaultInstance ③ 使用Session.getStore来获取服务器的POP3存取,也可以指定IMAP。 ④ 使用store.connect来创建一个从store 对象到实际服务器上的活连接。 ⑤ 用store.getFolder找到INBOX(收件箱)文件夹(POP3存储里唯一的文件夹),对IMAP 服务器而言,可以访问不同的文件夹。用folder.open 以只读方式打开文件夹。 ⑥ folder.getMessages 获得一组消息,这个数组效率高,因此它仅当需要结果传输数据。使用JavaMail获取邮件,部分关键代码如下: (2)发送电子邮件 发送电子邮件消息涉及到获取会话、创建和填充消息并发送消息这些操作。在获取Session时,通过为要传递的Properties 对象设置mail.smtp.host属性来指定所用的SMTP服务器。 (3)转发电子邮件 转发消息涉及的内容要稍微多一点,没有一个专门用于转发消息的方法,可以通过处理组成消息的各个部分来创建要转发的消息。一条邮件消息可由多个部分组成,每一部分是一个BodyPart(报文部分),或更特殊一点,在操作MIME消息时则是MimeBodyPart[11]。不同的报文部分组合到一个称为Multipart的容器中,或者更特殊一点,是一个MimeMultipart 容器。要转发消息,用户需要创建一个用于消息文本的部分,和用于要转发的消息的第二个部分,并将这两个部分组合成一个Multipart(多个部分)。然后, 可以把这个Multipart添加到一个合适的注明地址的消息中并发送它。 这就是转发消息的过程。要把一条消息的内容复制给另一条消息,只需通过它的ataHandler类复制即可,它是出自于JavaBeans Activation Framework的一个类。 上面着重分析和探讨基于JavaMail API 的邮件服务系统的设计和实现的相关技术。为系统实际开发过程中充分利用Java编程语言的开放性、平台无关性等优点,极大地提高了系统的效率和性能。 系统实现
Javamail API使邮件的发送与接收得到大大的简化。本文所开发的邮件客户端程序是在Eclipse 环境下实现的。其主要实现如下基本功能: (1) 收取并显示POP3邮件服务器上指定邮箱的邮件; (2) 使用SMTP邮件服务器发送邮件; (3) 邮件附件的发送与接受; (4) 删除邮件; 邮件客户端的功能界面如下图4-1所示: 4.1环境配置与界面搭建 在Eclipse中创建工程后,首先为工程添加javamail和javabeansActivationFrame Work开发包,然后使用swing图形工具包搭建各个程序界面,并在使用Javamail API的类文件中导入相关的API包,即在程序的开头添加下面的语句: 4.2设置邮件服务器参数的实现 用户在收发邮件时,需要设置邮件服务器主机、收发邮件帐户及密码等信息。因此系统提供对上述信息的设置与存储的功能,这里,我们采用属性文件的形式存储SMTP 和POP3邮件服务器属性设置。其文件名为smtpPop3.properties,位于工程的根目录下,可使用java.uitl. Properties类的setProperty()方法和getProperty()方法[14]对属性文件中的属性内容进行存取。本系统smtp Pop3.properties文件的内容格式如下: smtpPop3.pop3host=pop3邮件服务器地址(如pop3.sina.com.cn ) smtpPop3.smtphost=smtp邮件服务器地址(如smtp.sina.com.cn) smtpPop3.address=收发邮件帐户(如xyz@sina.com) smtpPop3.username=用户名(如xyz) smtpPop3.password=密码(如654321) 4.3 创建与发送邮件功能的实现 发送邮件的基本过程为:点击主界面中的“创建邮件”按钮后,弹出新邮件编辑窗体,在该窗体中编辑新邮件,选择邮件附件后,点击“发送”按钮,程序根据输入的邮件信息构造邮件,并将其发送。其具体实现步骤和关键代码为: 4.3.1 装载邮件服务器属性, 并与其建立连接 用java.uitl.Properties类的getProperty ()方法从属性文件smtpPop3.properties中取得smtp邮件服务器的地址、用户帐号、用户邮箱地址、密码信息,创建与SMTP 服务器连接的Session会话。 4.3.2 构建邮件 获取收件人地址、抄送人地址、邮件主题、附件等信息构建邮件。包括设置邮件标题&发送时间,处理邮件正文和附件文件。这里,在构建邮件时,对含有中文字符的附件文件名,进行BASE64 [15]编码,否则,收邮件时附件名将为乱码。程序中使用类sun.mism.BASE64Encoder实现BASE64 编码。 4.4 接收邮件功能的实现 在点击“接收邮件”按钮后,用户可以收取并阅读邮件。这时,系统首先从指定接收邮件的服务器中收取邮件,并将邮件的发件人、邮件主题以及邮件日期信息以列表形式显示出来;其次是在该邮件列表中点击某封邮件时, 可以显示该邮件的详细信息,包括邮件内容、附件列表等。其具体实现步骤和关键代码如下: 4.4.1 获取服务器信息 与发送邮件时获取SMTP 服务器属性一样,接收邮件时要从smtpPop3.properties文件中取得Pop3 服务器信息, 并建立Session 会话。 4.4.2 建立通信连接 获取邮件服务器上的邮件夹,并将其以列表形式显示,代码如下[16]: 4.4.3显示邮件 在邮件显示列表中点击某封邮件,根据该邮件的编号获得该邮件并存放在一个Message 对象message 中,然后使用Message类所提供的方法将邮件的主题、发件人、收件人、邮件体、附件信息解析并显示出来。如果将这个邮件显示在一个面板viewPanel中,则ViewPanel 类的主要代码如下。其效果图如图4-4。 LoadBody(Part part)方法用来解释并显示邮件内容与附件。方法的入口参数是一个Part 类型的参数, Part 为一个接口, Message 类、BodyPart 类等都实现该方法。调用方法时传入的参数为一个Message 对象。解释邮件的基本思路为:当邮件为Multipart 类型时, 依次取出邮件的各个部分;如果邮件的某个部分不为Multipart 类型, 则该部分应为正文或附件;此时再使用getDisposition()方法进一步判断该部分为正文还是附件, 方法返回值为null 时为正文, 方法返回值为Part.ATTACHMENT 或为Part.INLINE 时为附件。loadBody (Part part) 方法需要用到的类为:javax.mail.internet.MimeBodyPart、javax.activation.FileDataSource、javax.mail.Multipart、javax.mail.MimeMultipart、javax.mail.BodyPart[17]。其中Multipart 类和BodyPart 类是抽象类,MimeMultipart 类和MimeBodyPart 类分别是继承于Multipart 类和BodyPart 类并支持MIME 的实现类, 而FileDataSource 是用来处理附件的类。 4.5 删除邮件功能的实现 用户点击系统主窗体的,删除邮件-按钮后,系统将邮件的表格中当前被选中的邮件删除,并刷新邮件显示表格。其实现代码如下: 其中deleteIndex为被选中邮件在邮件列表中的序号,由邮件显示表格的时间程序获得。 上面使用javamail API所实现的邮件客户端程序具备了一个Email收发系统的基本功能,在此基础上,可以进一步添加其它的功能,比如转发邮件、回复邮件等,使其成为一个功能完善的邮件客户端系统。
版权所有© 帮我毕业网 并保留所有权利