1、课程设计I报告题 目: 电子邮件系统设计 1、 课题名称电子邮件系统设计2、 课题内容设计一个电子邮件系统,包括客户端和服务器端的设计、邮件处理过程建模和具体功能的实现等。3、 系统分析电子邮件(e-mail)是因特网上使用得最多的和最受用户欢迎的一种应用。电子邮件把邮件发送到 ISP 的邮件服务器,并放在其中的收信人邮箱中,收信人可随时上网到 ISP 的邮件服务器进行读取。电子邮件不仅使用方便,而且还具有传递迅速和费用低廉的优点。现在电子邮件不仅可传送文字信息,而且还可附上声音和图像。本系统分析中给出了电子邮件服务器和电子邮件客户端的简介,同时给出了本次试验中客户端的主要功能和总体框图。邮件
2、服务器按照提供的服务类型,可以分为发送邮件服务器(简称发送服务器)和接收邮件服务器(简称接收服务器)。发送邮件服务器使用邮件发送协议,现在常用的是SMTP,所以通常发送邮件服务器也称为SMTP服务器;接收邮件服务器使用接收邮件协议,常用的有POP3协议和IMAP协议,所以通常接收邮件服务器也称为POP3服务器或IMAP服务器。SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议,是Internet传送E-mail的基本协议,也是TCP/IP协议组的成员。SMTP协议解决邮件系统如何通过一条链路,把邮件从一台机器传送到另一台机器上的问题。SMTP协议的特点是
3、具有良好的可伸缩性,这也是它成功的关键。它既适用于广域网,也适用于局域网。SMTP协议由于非常简单,使得它得到了广泛的运用,在Internet上能够发送邮件的服务器几乎都支持SMTP协议。POP3(Post Office Protocol 3),即邮局协议第3版,是 Internet接收邮件的基本协议,也是TCP/IP协议组的成员。RFC1939描述了POP3协议,网址为“http:/www.ietf.org/rfc/rfc1939.txt”。POP3既允许接收服务器向邮件用户发送邮件,也可以接收来自SMTP服务器的邮件。邮件客户端软件会与POP3服务器交互,下载由POP3服务器接收到的邮件。
4、基于POP3协议的邮件系统能提供快速、经济和方便的邮件接收服务,深受用户的青睐。IMAP(Internet Message Access Protocol),即互联网消息访问协议,是一种功能比POP3更强大的新的接收邮件协议。目前最新的IMAP协议版本为IMAP4,RFC2060描述了IMAP4,网址为“http:/www.ietf.org/rfc/rfc2060.txt”。IMAP4与POP3协议一样提供了方便的下载邮件服务,允许用户在脱机状态下阅读已经下载到本地硬盘的邮件。但IMAP4的功能远远不只这些,它还具有以下功能: 摘要浏览邮件的功能。选择性下载附件的功能。鼓励用户把邮件一直存储在
5、邮件服务器上。允许用户把远程邮件服务器上的邮箱作为信息存储工具。MIME(Multipurpose Internet Mail Extensions,多用途Internet邮件扩充标准)不是邮件传输协议,而是对邮件格式所作的规范。RFC2045、RFC2046和RFC2047对MIME作了描述。MIME是对RFC822的扩充,RFC822规定了内容只包括采用ASCII编码的纯文本的邮件的格式,而MIME允许在邮件中包含附件。整个电子邮件系统的工作过程及一些涉及到的协议如下图所示:电子邮件系统包含:电子邮件服务器端和电子邮件客户端。SUN公司制定了JavaMail API,它封装了按照各种邮件通
6、信协议,如IMAP、POP3和SMTP,与邮件服务器通信的细节,为Java应用程序提供了收发电子邮件的公共接口,参见下图:JavaMail API主要位于javax.mail包和javax.mail.internet中,下图为其中主要类的类框图。1. javax.mail.Session类:表示邮件会话,是JavaMail API的最高层入口类。2javax.mail.Store类:表示接收邮件服务器上的注册用户的存储空间,通过Store类的getFolder()方法,可以访问用户的特定邮件夹。 3. javax.mail.Folder类:代表邮件夹。4. javax.mail.Message
7、类:代表电子邮件。5. javax.mail.Address类:代表邮件地址。6. javax.mail.Transport类:根据指定的邮件发送协议(通常是 SMTP),通过指定的邮件发送服务器来发送邮件。电子邮件服务器的最简模型如下图:电子邮件服务器的结构一般如下图所示:电子邮件服务器还能在本机和客户端进行连接使用(即主机上的SMTP服务器还可能与其他SMTP服务器会话以发送邮件)如下图:按照MIME规范,电子邮件包括邮件头和正文两部分。邮件头中包括日期、发送者地址、接收者地址和主题等信息。正文部分可以包括普通文本内容,还可以包括一个或多个附件。javax.mail.Message抽象类表
8、示邮件,它的具体子类为javax.mail.MimeMessage类,它提供了读取和设置邮件中各个部分的getXXX()和setXXX()方法:setSubject(String subject)方法设置邮件的主题。setHeader(String name, String value)方法设置邮件头部的某一项。setContent(Object o, String type)方法设置邮件的正文。javax.mail.Address抽象类表示邮件地址,它的最常用的子类是javax.mail.InternetAddress类。InternetAddress类表示Internet网上通用的邮件地址
9、,形式为admin,或者“Admin”。电子邮件客户端是安装在个人电脑上面的一种软件,用于和电子邮件服务器端的连接。基本上所有的客户端一般都有以下四个基本功能: a.通过POP3收取用户各种邮箱的邮件。由于考虑到POPular服务器地址的不同,但又可以接收不同邮箱地址的邮件,所以增加了这个功能。 b.在线阅读邮件,这个功能是电子邮件系统必备的功能。 c.接收保存邮件,用户可以再阅读邮件之后,将其保存起来,在需要的时候再次阅读。 d.在线处理邮件,如果收到一些垃圾邮件或者不是很重要的邮件,那么用户可以将它们放到垃圾箱或者然后在去垃圾箱中将它彻底删除,这是最好的办法。这个时候就要引入在线处理邮件功
10、能,这个功能能够删除邮件。 e.发送附件。有时候邮件太长,或者是表格、Word文档,一正文方式发送不太方便,这样可以引用一个附件功能。及那个这些表格或Word文档以附件的形式上传,让后发送。在扩充一下,提供可以发送多个邮件的功能。(本功能为扩展功能,本系统并未实现)。 f.接收附件,相对于发送附件而言,接收附件的功能必不可少。不然不能阅读邮件的内容。同样,应该扩充可以接受多个附件的功能。 g.SMTP验证,当前大部分的SMTP服务器,在用户发送邮件的时候,都需要进行用户名和密码的验证。 h.邮件文件夹管理,该功能提供了用户可以再除了了有收件箱等必须得文件夹时,可以根据自己的需要创建新的文件夹用
11、于更好大的管理自己收到的邮件,还可以重命名和删除用户自己创建的文件夹。 i.回复邮件,该功能是电子邮件系统必备的功能 下面列出了本系统的总体功能:总之,由上面的电子邮件服务器和客户端的分析可知该电子邮件系统收发邮件的整个过程和图示如下:(1) 发信人调用用户代理来编辑要发送的邮件。用户代理用 SMTP 把邮件传送给发送端邮件服务器。(2) 发送端邮件服务器将邮件放入邮件缓存队列中,等待发送。(3) 运行在发送端邮件服务器的 SMTP 客户进程,发现在邮件缓存中有待发送的邮件,就向运行在接收端邮件服务器的 SMTP 服务器进程发起 TCP 连接的建立。(4) TCP 连接建立后,SMTP 客户进
12、程开始向远程的 SMTP 服务器进程发送邮件。当所有的待发送邮件发完了,SMTP 就关闭所建立的 TCP 连接。(5) 运行在接收端邮件服务器中的 SMTP 服务器进程收到邮件后,将邮件放入收信人的用户邮箱中,等待收信人在方便时进行读取。收信人在打算收信时,调用用户代理,使用 POP3(或 IMAP)协议将自己的邮件从接收端邮件服务器的用户邮箱中的取回(如果邮箱中有来信的话)。4、 系统设计本系统基于JavaMial API采用B/S设计结构。使用Apache Tomcat做为WEB服务器和JSP Servlet的容器。JDK中并不包含JavaMail API。为了开发JavaMail应用程序
13、,需要从SUN公司的网站下载JavaMail API及其实现的类库,该类库由两个JAR文件组成: mail.jar和activation.jar。JavaMail应用程序在初始化过程中需要执行如下步骤。步骤(1)设置JavaMail属性: Properties props = new Properties();props.put(mail.transport.protocol, smtp);props.put(mail.store.protocol, imap);props.put(mail.smtp.class, com.sun.mail.smtp.SMTPTransport);props.
14、put(mail.imap.class, com.sun.mail.imap.IMAPStore);props.put(mail.smtp.host, hostname); 以上代码设置了如下JavaMail属性:mail.transport.protocol:指定邮件发送协议。mail.store.protocol:指定邮件接收协议。mail.smtp.class:指定支持SMTP协议的Transport具体类,允许由第三方提供。mail.imap.class:指定支持IMAP协议的Store具体类,允许由第三方提供。mail.smtp.host:指定采用SMTP协议的邮件发送服务器的IP地
15、址或主机名步骤(2)调用javax.mail.Session类的静态方法Session.getDefaultInstance()获得Session实例,该方法根据已经配置的JavaMail属性来创建Session实例:Session mailsession = Session.getDefaultInstance(props);步骤(3)调用Session的getStore(String protocol)方法来获得Store对象,参数protocol指定接收邮件协议:Store store = mailsession.getStore(imap);步骤(1)把mail.imap.class属
16、性设为com.sun.mail.imap.IMAPStore,因此以上getStore()方法返回com.sun.mail.imap.IMAPStore类的实例。步骤(4)调用Store对象的connect()方法连接到接收邮件服务器。调用connect()方法时,应该指定接收邮件服务器的主机名或IP地址、用户名和口令。 store.connect(hostname,username, password);获得了Store对象后,就可以通过它来访问邮件服务器上的特定邮件用户了。通常会对邮件用户执行以下操作。操作(1)创建并发送邮件:/创建邮件msg = new MimeMessage(mail
17、session);InternetAddress toAddrs =InternetAddress.parse(admin, false);/设置邮件接收者 msg.setRecipients(Message.RecipientType.TO, toAddrs);/设置邮件的主题msg.setSubject(hello);/设置邮件的发送者msg.setFrom(new InternetAddress(admin);/设置邮件的正文msg.setText(How are you);/发送邮件Transport.send(msg);Transport的静态方法send(Message)负责发送邮
18、件服务器,邮件发送协议由mail.transport.protocol属性指定,邮件发送服务器由mail.smtp.host属性指定。操作(2)打开inbox邮件夹收取邮件:/获得名为“inbox”的邮件夹Folder folder=store.getFolder(inbox);/打开邮件夹folder.open(Folder.READ_ONLY);/获得邮件夹中的邮件数目System.out.println(You have +folder.getMessageCount()+ messages in inbox.);/获得邮件夹中的未读邮件数目System.out.println(You
19、have +folder.getUnreadMessageCount()+ unread messages in inbox.);在IMAP协议中,inbox邮件夹是邮件用户的保留邮件夹,用户不允许删除该邮件夹,邮件服务器把所有接收到的新邮件都存在该邮件夹中。操作(3)从邮件夹中读取邮件:/从邮件夹中读取第一封邮件Message msg=folder.getMessage(1);System.out.println(-the first message in inbox-);/获得邮件的发送者、主题和正文System.out.println(From:+msg.getFrom()0);Syst
20、em.out.println(Subject:+msg.getSubject();System.out.println(Text:+msg.getText();系统设计中,给出了本次试验的UML建模和系统各个模块的划分。一、UML建模1. 本系统的用例图:图中User是本系统的总用户,Sender和Receiver分别为发送邮件者和接收邮件者是从User中泛化出来的。Upload accessory表示为上传附件用例;Sending mail表示为发送邮件用例;Longin表示为登录用例;Receiving mail表示为接收邮件用例;Saving mail表示为保存邮件用例;Saving a
21、ccessory表示为保存附件用例;Folder表示为管理邮件文件夹用例;Create new folder表示为创建新的邮件文件夹用例;Rename folder表示为重命名创建的邮件文件夹用例;Delete folder表示为删除创建的邮件文件夹;Deleting mail表示为删除用户收到的邮件用例。2. 本系统的时序图和对应的协作图:(1) 用户发送邮件的时序图:从上图中可以看出,首先用户得登录系统,在登录系统时还可以选择登入服务器。用户正常登录系统后,系统会将用户的ID保存在session变量中,并传递给发送和回复邮件模块。用户打开发送邮件界面就可以发送邮件了。界面提示输入相关邮件信
22、息,按提示输入收件人邮件地址、主题和内容等信息后,单击“发送”按钮就可以发送了。有时候需要发送附件,单击“添加附件”命令选择需要添加的文件就可以了。最后提示发送成功。(2) 用户接收邮件的时序图:从上图中可以看出,用户首先还是先登录邮件系统,然后系统将所有提交用户的ID保存到session变量中,并传递给接收邮件模板。该界面列出了所有的邮件,用户可以打开某个邮件阅读。有时候邮件是以附件的形式发送的,这样用户在接收邮件是就需要先下载附件,然后保存。(3) 用户发送邮件的协作图:这是与上面用户发送邮件的时序图对应的协作图。(4) 用户接收邮件的协作图:这是与上面用户接收邮件的时序图对应的协作图。3
23、. 本系统的总体分析模型(类图):该类图中包含了两个类:PMessage和MailUserData。其中PMessage类对Message类的重新封装,提供更方便的读取邮件信息的方法。例如,在Message类中读取邮件地址的方法,如getTo()方法返回Address类型,如果要把它显示到网页上,必须把Address数组转化为对应的字符串。PMessage的构造方法PMessage对Message数据重新封装。JSP网页调用PMessage的getTo方法可以直接获得字符串类型的地址。MailUserData类用来存放用户的相关信息,还有对邮件文件夹操作的一些方法的定义,还有邮件管理的一些操作
24、的定义,例如:发送邮件,删除邮件等。4. 本系统的活动图: a.用户接收邮件的活动图,在接收邮件是可以分两种方式,一种是文本形式,另一种是附件形式。接收邮件后,用户可以并列做3件事,即保存邮件、删除邮件和将邮件放入垃圾箱。至此,用户接收邮件的活动完成。b.用户发送邮件的活动图,在发送邮件的活动中,还是一样,用户首先必须登录邮件系统,这样,以后的操作才可以进行。发送的主要活动就是发送邮件一个,它以两种形式发送的。c.用户管理邮件文件夹的活动图,用户可以根据自己的需要新建邮件文件夹、重新命名创建的文件夹和删除创建的文件夹。5. 本系统的组件图:二、系统模块的划分按照本系统的总体功能划分,可以将这个
25、电子邮件系统分成5大模块,首先是登录模块,作为验证需要;其次是接收邮件和附件模块,该模块负责邮件的接收,有的是以附件形式接收的,再次是发送和回复模块,该模块负责该对方发送邮件,有的还是以附件形式发送的;接着是邮件处理模块,该模块负责邮件的阅读、保存和删除等操作;然后是邮件文件夹的管理,该操作负责邮件文件夹的新建、重命名和删除等操作。下面累出了本系统的模块体系,如图:1 登录模块登录模块主要有login.jsp完成,其中包括下图中的几部分。(1) 选择登录服务器,本系统采用了MerakMailSErvler公司提供的Mail服务器使用版本。(2) 选择指定邮件地址和密码。在本系统中有所提供的Ma
26、il服务器创建了2个账户进行登录。必须选用正确的邮件地址和密码才可以登录,不然会报错。登录模块的图示:2.接收邮件和附件模块接收邮件和附件模块主要由showmessage.jsp文件完成,包括下图中的几个部分。(1) 接收邮件。一个邮件系统最基本的功能就是能够接受对方发送的邮件。(2) 保存附件。如果对方是以附件的形式发送邮件给用户,那么用户在接收邮件时,必须先下载邮件,将其保存到本地机之后,才能阅读。接收邮件和附件模块的图示:3.发送和回复邮件模块 发送和回复邮件模块主要由compose.jsp文件完成,包括图中的几个部分。(1) 编写新邮件。该部分也是电子邮件系统中最基本的功能。(2) 上
27、传附件。在编写邮件时,邮件内容可以以附件的形式发送,这样就需要先将附件上传到服务器,然后在发送给对方。 发送和回复邮件模块的图示:4.邮件处理模块邮件处理模块主要由listonefoldr.jsp文件完成,包括图中的几个部分。(1) 显示邮件列表。在登录后的首页中就以分页显示的形式列出了所有的邮件,便于管理。(2) 删除选中邮件。在选中删除的邮件后,可以单击该命令删除邮件。(3) 显示错误信息。在出现一些登录错误,删除错误,下载错误是,将显示不同的错误信息提示用户。邮件处理模块的图示:5.邮件文件夹管理模块邮件文件夹管理模块主要是由listallfolders.jsp文件完成,包括图中的几个部
28、分。(1) 创建新的邮件文件夹。用户可以根据自己的需要创建新的邮件文件夹,便于管理用户的邮件。(2) 重命名邮件文件夹。用户可以重新命名自己创建的邮件文件夹。(3) 删除邮件文件夹。用户可以删除自己创建的邮件文件夹。邮件文件夹管理模块的图示:5、 系统实现1 服务器的安装和配置1.在做本次系统之前,必须配置JSP的服务器和电子邮件的服务器。(1)JSP的服务器,主要使用的是Tomcat,同时在安装Tomcat服务器之前,必需已经安装了SUN公司的JDK,在安装Tomcat的时候主要是注意电脑环境变量的更改。安装完成后,只要在浏览器中输入http:/localhost:8080/看是否能打开To
29、mcat的网页,如果能,则表示安装成功,8080端口是Tomcat的默认端口,如果电脑上有服务已经把端口占用了,可以把占用该端口的服务关掉,如果该服务关不掉或者比较重要,可以再Tomcat的安装目录中找到server.xml文件,将其中port=8080改成没有被占用的端口号。(2)电子邮件服务器的配置:在本系统中我们采用了MerakMailServler公司的Mail服务器,安装完成后,在配置中输入本次实验所需要的域名和用户等信息。然后保存,配置完成。2 客户端的实现给出本系统中包含的两个类:由于代码比较多,所以这里只给出了核心代码。首先要加入一个中文字符串处理函数用于是邮件能发送中文:pu
30、blic String codeToString(String str)/处理中文字符串的函数 String s=str; try byte tempB=s.getBytes(ISO-8859-1); s=new String(tempB); return s; catch(Exception e) return s; 1. PMessage类重新封装了Message类。(1) 重新封装Message类获得邮件的时间、主题、大小、内容还有地址等; public PMessage(Message msg)throws Exception if(msg!=null) SimpleDateForma
31、t df = new SimpleDateFormat(yy.MM.dd at HH:mm:ss ); trydate=df.format(msg.getSentDate()!=null) ? msg.getSentDate() : msg.getReceivedDate(); catch(Exception e)date=new Date().toString(); subject=msg.getSubject(); size=msg.getSize(); Object content=; try content=msg.getContent(); catch(Exception e) if
32、(msg.isMimeType(text/plain) & content!=null) text=(String)content; from=assembleAddress(msg.getFrom(); to=assembleAddress(msg.getRecipients(Message.RecipientType.TO); cc=assembleAddress(msg.getRecipients(Message.RecipientType.CC); bcc=assembleAddress(msg.getRecipients(Message.RecipientType.BCC); (2)
33、构造函数PMessage(String to,String cc,String bcc,String subj,String text); public PMessage(String to,String cc,String bcc,String subj,String text) to.replace(;,); cc.replace(;,); bcc.replace(;,); this.to=to; this.cc=cc; this.bcc=bcc; this.subject=subj; this.text=text; (3)将Address数组转化为对应的字符串,用于在页面上显示; pri
34、vate String assembleAddress(Address addr) if(addr=null)return ; String addrString=; boolean tf = true; for (int i = 0; i addr.length; i+) addrString=addrString+(tf) ? : , ) + getDisplayAddress(addri); tf = false; return addrString; (4)返回一个适合msg头的字符串。 private String getDisplayAddress(Address a) Strin
35、g pers = null; String addr = null; if (a instanceof InternetAddress & (pers = (InternetAddress)a).getPersonal() != null) addr = pers + +<+(InternetAddress)a).getAddress()+> else addr = a.toString(); return addr; ;2.MailUserData类 (1)删除用户自己创建的邮件夹,但不允许删除Web应用指定的系统邮件夹; public void doDeleteFolder(S
36、tring foldername )throws Exception /cant delete reserved folder if(foldername.equalsIgnoreCase(inbox)| foldername.equalsIgnoreCase(trash)| foldername.equalsIgnoreCase(draft)| foldername.equalsIgnoreCase(sendbox) throw new Exception(Cannt delete reserved folder); Folder folder=store.getFolder(foldern
37、ame); if(!folder.exists()throw new Exception(This folder does not exists); if(folder.isOpen()folder.close(true); folder.delete(true); (2)修改用户自己创建的邮件夹的名字,但不允许修改Web应用指定的系统邮件夹得名字; public void doRenameFolder(String fromname,String toname)throws Exception if(toname=null | toname.equals() throw new Except
38、ion(You do not input new folder name when renaming folder); /cant rename reserved folder if(fromname.equalsIgnoreCase(inbox)| fromname.equalsIgnoreCase(trash)| fromname.equalsIgnoreCase(draft)| fromname.equalsIgnoreCase(sendbox)| toname.equalsIgnoreCase(inbox)| toname.equalsIgnoreCase(trash)| toname
39、.equalsIgnoreCase(draft)| toname.equalsIgnoreCase(sendbox) throw new Exception(Cannt rename reserved folder); Folder folderFrom=store.getFolder(fromname); Folder folderTo=store.getFolder(toname); if(!folderFrom.exists()throw new Exception(This folder does not exists); if(folderFrom.isOpen()folderFro
40、m.close(true); folderFrom.renameTo(folderTo); (3) 创建用户自己的邮件夹; public void doCreateFolder(String foldername)throws Exception if(foldername=null | foldername.equals() throw new Exception(You do not input new folder name when creating folder); Folder folder=store.getFolder(foldername); if(folder.exists
41、()throw new Exception(This folder already exists); folder.create(Folder.HOLDS_MESSAGES); (4) 把邮件添加到参数指定的邮件夹中; public void doAppendMessage(Message msg, Folder f)throws Exception Message m=new Message1; m0=msg; f.appendMessages(m); (5) 根据参数指定的邮件信息,如标题,收发地址和邮件内容,来构建Message对象; public Message doAssembleM
42、essage(String to,String cc,String bcc,String subj,String text)throws Exception Message msg = new MimeMessage(session); InternetAddress toAddrs = null, ccAddrs = null, bccAddrs=null; if (to != null) toAddrs = InternetAddress.parse(to, false); msg.setRecipients(Message.RecipientType.TO, toAddrs); else
43、 throw new MessagingException(No To address specified); if (cc != null) ccAddrs = InternetAddress.parse(cc, false); msg.setRecipients(Message.RecipientType.CC, ccAddrs); if (bcc != null) bccAddrs = InternetAddress.parse(bcc, false); msg.setRecipients(Message.RecipientType.BCC, bccAddrs); if (subj != null) msg.setSubject(subj); msg.setFrom(new InternetAddress(urlName.getUsername() + + urlName.getHost(); if (text != null) msg.setText(text); return msg; (6) 如果该邮件在Tra