购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.3 JSP与JavaMail

电子邮件成了人们生活与工作的基本组成部分。越来越多的Java Web应用需要集成电子邮件的功能,JavaMail组件的诞生完美地解决了这个问题。

4.3.1 电子邮件工作原理

电子邮件的工作过程遵循客户—服务器模式。每份电子邮件的发送都要涉及发送方与接收方,发送方充当客户端,而接收方充当服务器,服务器含有众多用户的电子信箱。发送方通过邮件客户程序,将编辑好的电子邮件向邮局服务器(SMTP服务器)发送。邮局服务器识别接收者的地址,并向管理该地址的邮件服务器(POP3服务器)发送消息。邮件服务器将消息存放在接收者的电子信箱内,并告知接收者有新邮件到来。接收者通过邮件客户程序连接到服务器后,就会看到服务器的通知,进而打开自己的电子信箱来查收邮件。

具体工作流程如图4-6所示。

图4-6 电子邮件工作流程

电子邮件在发送与接收过程中都要遵循SMTP、POP3等协议,这些协议确保了电子邮件在各种不同系统之间的传输。其中,SMTP负责电子邮件的发送,而POP3则用于接收Internet上的电子邮件。

4.3.2 相关协议介绍

在介绍JavaMail之前,我们先了解一下JavaMail所涉及的相关协议。

1.SMTP协议

SMTP协议(Simple Mail Transfer Protocol)是为了保证电子邮件的可靠和高效传送。TCP/IP协议的应用层中包含SMTP协议,但事实上它与传输系统和机制无关,仅要求一个可靠的数据流通道。它可以工作在TCP上,也可以工作在NCP、NITS等协议上。在TCP上,它使用端口 25进行传输。SMTP的一个重要特点是可以在可交互的通信系统中转发邮件。

SMTP为我们提供了一种邮件传输的机制,当收件方和发件方都在一个网络中时,可以把邮件直传给对方;当双方不在同一个网络中时,需要通过一个或几个中间服务器转发。SMTP首先由发件方提出申请,要求与接收方SMTP建立双向的通信渠道,收件方可以是最终收件人也可以是中间转发的服务器。收件方服务器确认可以建立连接后,双方开始通信,直至邮件发送到目的地。

2.POP3协议

POP的全称是Post Office Protocol,即邮局协议,用于电子邮件的接收,现在常用的是第三版,简称为POP 3。POP定义了一种用户如何获得邮件的机制,它规定了每个用户使用一个单独的邮箱。

POP服务器一般使用的是TCP的 110 号端口,通过POP协议,客户机登录到服务器上后,可以对自己的邮件进行删除或下载到本地,下载后,电子邮件客户软件就可以在本地对邮件进行修改、删除等操作。

3.IMAP协议

IMAP(Internet消息访问协议)是与POP3对应的另一种协议,为美国斯坦福大学在 1986年开始研发的多重邮箱电子邮件系统。它能够从邮件服务器上获取有关E-mail的信息或直接收取邮件,具有高性能和可扩展性的优点。IMAP被很多客户端电子邮件软件所采纳,如Outlook Express、Netscape Messenger等,支持IMAP的服务器端的软件也越来越多,如Critical Path、Eudora、iPlanet、Sendmail等。

读者也许要问,POP3也是接收邮件的协议,现在不是用得很好么,为何还要用IMAP协议呢?

的确,POP作为Internet上邮件的第一个离线协议标准,允许用户从服务器上把邮件下载到本地主机,同时删除保存在邮件服务器中的邮件,从而使用户不必长时间地与邮件服务器连接,很大程度上减少了服务器和网络的整体开销。

但POP3有其天生的缺陷,即当用户接收电子邮件时,所有的信件都从服务器上清除并下载到客户机。在整个收信过程中,用户无法知道邮件的具体信息,只有照单全收存入硬盘后,才能慢慢浏览和删除,这使用户几乎没有对邮件接收的控制决定权。一旦碰上邮箱被轰炸,或有比较大的邮件,用户不能通过分析邮件的内容及发信人地址来决定是否下载或删除,从而造成系统资源的浪费。而IMAP协议不但可以克服POP3的缺陷,而且还提供了更强大的功能。

尽管如此,IMAP依然存在一些不足之处,比如在利用服务器磁盘资源方面,IMAP不如POP 3。由于使用POP时服务器端的邮件被下载到客户机的同时会删除,因而不占用额外空间用以存放旧的邮件。而IMAP服务器将保持旧的邮件,占用了额外空间,而且需要定期地删除旧邮件。同时,由于用户查阅信息标题和决定下载哪些附件,也需要一定时间,因此链接时间也比POP方式长。

在应用方面,由于IMAP比较复杂,给开发者开发服务器和客户机的软件带来一些难题。对于ISP来说,采用IMAP意味着要花钱购买相关商业软件,同时会付出高额技术支撑费用,因而商用的实现方案还不多。

4.MIME

MIME并不是用于传送邮件的协议,它作为多用途邮件的扩展定义了邮件内容的格式,如信息格式、附件格式等。

例如:

text/html

text/plain

multipart/alternative

multipart/related

前两个就不必多讲,一个是html格式的正文,一个是无格式的文本正文。如果message对象是这两个mimetype中的一种的话,就可以直接显示它们。

如果message对象是后两种的话,就说明是multipart的。就需要做一些处理和判断分别得到multipart的各个部分(part)的内容,以得到整个message的内容。

4.3.3 JavaMail简介

JavaMail是Sun发布的用来处理E-mail的API,它支持各种电子邮件通信协议(如SMTP、POP3和IMAP等)。

要想在Java Web应用程序中使用JavaMail就要将JavaMail的mail.jar和activation.jar复制到WEB-INF/lib下。

通过调用JavaMail的API,即可在自己的应用程序中便捷地操作E-mail。

JavaMail API的核心类主要包括Session(会话)、Message(消息)、Address(地址)、Authenticator(验证程序)、Transport(传输)、Store(存储)和Folder(邮件夹)。

下面简单介绍这 7 个核心类。

1.Session(会话)类

就像Http会话一样,Session类定义了基本的邮件会话。邮件的收发工作都是基于这个会话进行的。Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。

Session类的构造方法是私有的,因此可以使用Session类提供的getDefaultInstance( )这个静态工厂方法获得一个默认的Session对象,如:

注:关于邮件授权的知识将在下文中进行介绍。

2.Message(消息)类

Message对象用来存储实际发送的电子邮件信息,Message对象被作为一个MimeMessage对象来创建,在创建时需要指定一个Session对象做参数。如:

//创建一个Message对象

MimeMessage message=new MimeMessage(mailSession);

创建完Message对象后,就可以为它设置一些信息。如:

//指定发件人邮箱

message.setFrom(new InternetAddress(from));

//指定收件人邮箱

message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));

//指定邮件主题

message.setSubject(subject);

//指定邮件发送日期

message.setSentDate(new Date());

//指定邮件优先级 1:紧急 3:普通 5:缓慢

message.setHeader('X-Priority','1');

在为Message对象添加内容时分两种情况,如果是文本型内容,可通过setText( )方法来设置,如:

//指定邮件内容

message.setText(content);

如果信息内容中要包含HTML或附件的话,可通过setContent( )方法来设置,如:

//指定邮件内容、ContentType及编码方式

message.setContent(content,'text/html;charset=gb2312');

3.Address(地址)类

当建立了Session和Message之后,下面将介绍如何使用邮件地址类Address为邮件标上地址。像Message一样,Address类也是一个抽象类,avax.mail.internet.InternetAddress是Address的子类,因此,可通过InternetAddress来创建Address对象。例如:

//定义发件人地址

Address from = new InternetAddress('e868_cn@163.com');

//定义收件人地址

Address to = new InternetAddress('dywdyw@163.com');

//为邮件设置发件人

message.setFrom(from);

//为邮件设置收件人

message.addRecipient(Message.RecipientType.TO, to);

下面是Message.RecipientType的3个常量:

·Message.RecipientType.TO(收件人)

·Message.RecipientType.CC(抄送)

·Message.RecipientType.BCC(密送)

4.Authenticator(验证程序)类

JavaMail API通过使用授权者类(Authenticator)以用户名、密码的方式访问邮件服务器。在使用Authenticator这个抽象类时,必须采用继承该抽象类的方式,并且该继承类必须具有返回PasswordAuthentication对象(用于存储认证时要用到的用户名、密码)的getPasswordAuthentication( )方法。并且要在Session中进行注册,让Session知道在认证时该使用哪个类。例如:

5.Transport(传输)类

Transport类根据指定的邮件发送协议(如SMTP),通过指定的账号和密码连接指定的邮件发送服务器发送邮件。如:

//创建一个Transport对象

Transport transport = mailSession.getTransport('smtp');

//连接SMTP服务器

transport.connect(SMTPHost, user, password);

//发送邮件

transport.sendMessage(message, message.getAllRecipients());

transport.close();

6.Store(存储)类

Store代表了存储邮件的邮件服务器,可从Session中获取特定类型的Store,然后根据指定的账号、密码及授权连接到Store。Store类实现特定邮件协议上的读、写、监视、查找等操作。通过Javax.mail.Store类可以访问Javax.mail.Folder类。如:

//创建一个授权验证对象

POP3Auth auth = new POP3Auth();

auth.setAccount(user,password);

//创建一个Session对象

Properties prop=new Properties();

prop.put('mail.pop3.host',POP3Host);

Session session=Session.getDefaultInstance(prop,auth);

//取得一个Store对象

Store store=session.getStore('pop3');

store.connect(POP3Host,user,password);

7.Folder(邮件夹)类

Folder类代表了邮件夹,通过Folder类可以访问邮件夹中的邮件。对于POP3 协议只有一个名为INBOX的Folder有效,而对于IMAP协议,可以访问多个Folder。通过Store对象的getFolder方法可取得一个Folder对象。如:

//取得一个Folder对象

folder=store.getDefaultFolder().getFolder('INBOX');

folder.open(Folder.READ_ONLY);

//取得所有的Message对象

Message[] msg=folder.getMessages();

4.3.4 使用JavaMail发送文本型邮件

文本型邮件是应用最广泛的一种邮件类型,本实例将使用JavaMail发送文本型邮件。用户通过在邮件书写页面textMail.htm(见例程4-11)中填写邮件表单,然后提交给邮件发送页面sendMail1.jsp(见例程4-13),由sendMail1.jsp调用封装邮件发送功能的SendTextMail(见例程4-12)实现邮件的发送。

本实例的视频教程请参考配套光盘的“视频教程”部分。

例程4-11 文本型邮件书写页面textMail.htm

例程4-12 封装发送文本型邮件功能的SendTextMail.java

例程4-13 发送文本型邮件的JSP页面sendMail1.jsp

运行效果如图4-7所示。

图4-7 textMail.htm运行效果

4.3.5 使用JavaMail发送HTML型邮件

内容为HTML网页的邮件叫做HTML型邮件,它与文本型邮件的主要区别在于MIME类型的不同,一个为“text/html”,一个为“text/plain”。本实例将使用JavaMail发送HTML型邮件。用户通过在邮件书写页面htmlMail.htm (见例程4-14)中填写邮件表单,然后提交给邮件发送页面sendMail2.jsp (见例程4-16),由sendMail2.jsp调用封装邮件发送功能的SendHtmlMail (见例程4-15)实现邮件的发送。

本实例的视频教程请参考配套光盘的“视频教程”部分。

例程4-14 HTML型邮件书写页面htmlMail.htm

例程4-15 封装发送HTML型邮件功能的SendHtmlMail.java

例程4-16 发送HTML型邮件的JSP页面sendMail2.jsp

运行效果如图4-8所示。

图4-8 htmlMail.htm运行效果

4.3.6 使用JavaMail发送带附件的邮件

带有附件的邮件叫做附件型邮件,在处理附件型邮件时,要为邮件体与附件分别创建BodyPart对象,然后将其置入MimeMultipart对象中作为一个整体进行发送。本实例将使用JavaMail发送带附件的邮件。用户通过在邮件书写页面attachMail.htm (见例程4-17)中填写邮件表单,然后提交给邮件发送页面sendMail3.jsp (见例程4-19),由sendMail3.jsp调用封装邮件发送功能的SendAttachMail (见例程4-18)实现邮件的发送。

本实例的视频教程请参考配套光盘的“视频教程”部分。

例程4-17 带附件型邮件书写页面attachMail.htm

例程4-18 封装发送带附件型邮件功能的SendAttachMail.java

例程4-19 发送附件型邮件的JSP页面sendMail3.jsp

运行效果如图4-9所示。

图4-9 attachMail.htm运行效果

4.3.7 使用JavaMail收取邮件

作为一个完整的邮件系统而言,收邮件是必不可少的,使用JavaMail API收取邮件之前先要指定POP3 服务器地址、登录账号与密码。本实例将使用JavaMail收取邮件,用户通过在POP3服务器登录信息录入页面receiveMail.htm(见例程4-20)中填写表单,然后提交给邮件列表的JSP页面MailList.jsp(见例程4-22),由MailList.jsp调用封装邮件收取功能的GetMail(见例程4-21)实现邮件的收取。

阅读邮件详情的JSP页面readMail.jsp (见例程4-23))同样是调用GetMail的readMail方法实现邮件详情的读取。

本实例的视频教程请参考配套光盘的“视频教程”部分。

例程4-20 POP3 服务器登录信息录入页面receiveMail.htm

例程4-21 封装收到邮件功能的GetMail.java

例程4-22 显示邮件列表的JSP页面MailList.jsp

例程4-23 阅读邮件内容的JSP页面readMail.jsp

运行效果如图4-10 和图4-11所示。

图4-10 MailList.jsp运行效果

图4-11 readMail.jsp运行效果

本实例的完整源代码请参考配套光盘的“源代码”部分。 2NfSeJnlN+S+rsr9p9Y2GTNdqgFYaFX1TKj4sXNz7XOMiUY7QIGSblg57fA8n755

点击中间区域
呼出菜单
上一章
目录
下一章
×