电子邮件收发系统设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
第1章引言 (2)
第2章需求分析 (3)
2.1产品可行性分析 (3)
2.2产品功能需求分析 (5)
2.2电子邮件系统收发邮件的过程 (5)
第3章总体设计 (7)
3.1本系统的总体架构模型: (7)
3.2系统模块的划分 (8)
第4章详细设计 (9)
4.1接收邮件模块 (9)
4.2发送和回复邮件模块 (9)
4.3邮件处理模块 (10)
4.4界面实现的流程图 (10)
4.5邮件发送过程的流程图 (11)
4.6邮件接收流程 (13)
4.7用户鉴权和客户端配置信息流程 (15)
4.8阅读邮件流程 (16)
第5章系统功能测试 (18)
5.1登陆界面及邮箱账户设置界面测试 (18)
5.2主界面测试 (18)
5.3发送界面与收件箱界面测试 (18)
5.4阅读邮件界面测试 (20)
第6章结论与展望 (21)
6.1结论 (21)
6.2展望 (21)
致谢 (22)
参考文献 (23)
附录 (24)
第1章引言
电子邮件(简称 E-mai1)又称电子信箱、电子邮政,表示通过电子通讯系统进行信件的书写、发送和接收,它是继电话、电报和传真之后最快捷、最方便的通讯工具,是 20 世纪人类最伟大的发明。

早在互联网流行很久以前,电子邮件就已经存在。

它是在主机-多终端的主从式体系中通过一台计算机终端向另一台计算机终端传送文本信息的相对简单方法发展起来的,也就是人们常说的 C/S 架构。

如今,电子邮件已经将人与人越来越紧密地联系在一起,成为人们生活的一部分。

通过电子邮件系统,人们可以用非常低廉的价格,以非常快速的方式,与世界上任何一个网络用户联系。

而电子邮件的形式也从原来的纯文本方式变成现在的 HTML 页面并加载附件的多彩形式,同时,人们还可以得到大量免费的新闻、专题邮件,并实现轻松的信息搜索,这是任何传统的方式也无法相比的。

电子邮件的使用简易、投递迅速、收费低廉、易于保存、全球畅通无阻,使得它被广泛地应用。

电子邮件收发系统基于Client/Server模式,主要功能通过收发电子邮件客户端程序实现。

收发电子邮件需要标准的会话协议支持,SMTP (SimpleMailTransferProtocol)用于发送电子邮件,POP3协议(PostOfficeProtocol)用于接收电子邮件。

电子邮件使人们的交流方式得到了极大的改变.人们平时所发送或接收的电子邮件,并不是由本机来实现 SMTP 协议与 POP3 协议,电子邮件内容全是存储在相应服务商的 POP3 服务器上,用户必须要登录到相应的服务器上才能进行浏览、查询或者删除操作,但是,在网络繁忙或大家集中传输数据的时候,人们可能收不到消息或者打开很慢.为了解决这一难题,我们开发了电子邮件收发系统,将邮件服务器上的内容保存到本地机器上,这样即使在网络断开的情况下,也能查询已存在本地机器上的邮件。

第2章需求分析
2.1 产品可行性分析
整个电子邮件系统由电子邮件服务器端和电子邮件客户端组成,其工作过程及一些涉及到的协议如图2.1所示:
图2.1 电子邮件系统工作过程图
其中SMTP是因特网电子邮件系统重要的应用层协议。

它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人邮箱所在邮件服务器传送到收信人邮箱所在邮件服务器。

SMTP是客户-服务器应用模式,由发信人的邮件服务器执行的客户端和收信人的邮件服务器执行的服务器端组成。

SMTP的客户端和服务器端同时运行在每个邮件服务器上。

当一个邮件服务器向其它邮件服务器发送邮件消息时,它是作为SMTP客户端。

当一个邮件服务器从其它邮件服务器接收邮件消息时,它是作为SMTP服务器端。

SMTP规范定义在RFC 821中,它的作用是把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。

SMTP限制所有邮件消息的信体必须是简单的7位ASCII字符格式。

这个限制使得二进制多媒体数据在由SMTP传送之前必须编码成7位ASCII文本;SMTP传送完毕之后,再把相应的7位ASCII文本邮件消息解码成二进制数据。

POP3是RFC 1939中定义的一个简单的邮件访问协议,其功能有限。

POP3开始于用户代理打开一个到POP3服务器端口号110的TCP连接。

POP3服务器与
邮件服务器运行在相同的服务器主机上,前者从用户的邮箱中读取并可能删除邮件消息,后者往用户的邮箱中写入邮件消息。

TCP连接建立好之后,POP3依次经历授权认证、处理和更新3个阶段。

在授权阶段,用户代理分别发出一个用户名和一个口令以认证下载邮件消息的用户。

在处理阶段,用户代理获取邮件消息,并可以标记待删除的邮件消息或去掉这些标记,获取邮件统计信息。

更新阶段发生在用户代理发出quit命令以结束当前POP3会话之后,期间POP3服务器删除己加过删除标记的邮件消息。

在POP3会话期间,用户代理发出命令,POP3服务器则对每个命令响应以一个应答。

可能的应答有两个:指出刚才的命令执行成功的+OK(有时后跟一个解释性消息)和指出刚才的命令执行有误的-ERR。

一个邮件的收发就是通过SMTP传递消息到对端邮件服务器,对端客户使用POP3协议从服务器上获得邮件的过程。

在本设计中,采用自己编写基于socket 的方法,来解析协议,进行邮件收发。

同时,在进行邮件收发,需要提供基于BASE64加密解密的鉴权信息,其中Base64是一种很简单的编码转换:对于待编码数据,以3个字节为单位,依次取6位数据并在前面补上两个0形成新的8位编码,由于3×8=4×6,这样3个字节的输入会变成4个字节的输出,长度上增加了1/3。

上面的处理还不能保证得到的字符都是可见字符,为了达到此目的,Base64制定了一个编码表,进行统一的转换,见表2.1。

码表的大小为26=64,这也是Base64名称的由来。

由于编码是以3个字节为单位,当剩下的字符数量不足3个字节时,则应使用0进行填充,相应地,输出字符则使用‘=’占位,因此编码后输出的文本末尾可能会出现1至2个‘=’。

表2.1 Base64编码表
BASE64的加密解析,SUN公司有自己内部专用的API,该API位于JRE/LIB
下,但是该API并没有javadoc,属于不推荐使用的方法,将在后续JDK版本中被剔除,因为本设计根据Base64编码表,自行编写Base64加密解密方法。

分析电子邮件传输过程中的协议和加密算法后,本设计进行自主开发是可行的。

2.2 产品功能需求分析
图2.2 系统总体功能图
其中本设计实现的是一个电子邮件客户端,类似于Outlook,有用户邮箱账户设置,登陆验证,接收邮件,阅读邮件,保存邮件,发送邮件等功能。

发送邮件:根据用户设置的公网邮箱账户或者一个公网不存在的自己私人域内的符合邮箱命名规范的邮箱账户,可实现对公网邮箱和本客户端(比如新浪,QQ,163)的邮件收发;若邮箱账户是自己随机设置的账户,则不可以向除本客户端以外的邮件服务器发送邮件;
接收邮件:接收来自本客户端私人邮箱发来的邮件,在接收邮件的同时,将对邮件进行默认保存,接收完成后,点击即可实现对邮件的阅读;
登陆验证:客户端在启动的时候,会对用户的账户信息与客户端内部保存的信息,进行鉴权,防止旁人使用客户端乱发垃圾邮件;
账号设置:这个功能主要是实现对邮件发送代理的选择,决定发送邮件功能的能力。

2.2电子邮件系统收发邮件的过程
图2.3 收发邮件过程图
(1)发信人调用用户代理来编辑要发送的邮件。

用户代理用 SMTP 把邮件传送给发送端邮件服务器。

(2)发送端邮件服务器将邮件放入邮件缓存队列中,等待发送。

(3)运行在发送端邮件服务器的 SMTP 客户进程,发现在邮件缓存中有待发送的邮件,就向运行在接收端邮件服务器的 SMTP 服务器进程发起 TCP 连接的建立。

(4)TCP 连接建立后,SMTP 客户进程开始向远程的 SMTP 服务器进程发送邮件。

当所有的待发送邮件发完了,SMTP 就关闭所建立的 TCP 连接。

(5)运行在接收端邮件服务器中的 SMTP 服务器进程收到邮件后,将邮件放入收信人的用户邮箱中,等待收信人在方便时进行读取。

收信人在打算收信时,调用用户代理,使用 POP3(或 IMAP)协议将自己的邮件从接收端邮件服务器的用户邮箱中的取回(如果邮箱中有来信的)。

第3章总体设计
3.1 本系统的总体架构模型:
图3.1 系统的总体模型图
图3.1是该客户端的系统架构图,图中包含了六个图形用户界面,两个邮件接收和发送线程,以及一些相关的辅助方法和数据模型。

其中,各个图形用户界面是为了方便用户使用该客户端而设计;
用户鉴权和客户端配置信息,是主界面在加载时,针对每个特定的用户,加载其个人设置;
用户信息模型和账户信息模型用来对用户进行登录验证,设置邮箱账户时的信息进行封装。

发送邮件线程等待来自客户的发送请求,收到请求后,首先根据SMTP模型和用户输入信息,封装一个SMTP消息对象;接着对用户账户和密码进行BASE64加密;最后将封装好的信息对象,交由发送邮件方法进行发送;
邮件接收线程是客户端加载成功后,就开始监听25端口,当有邮件信息发
送到来时,将接收到的信息封装到一个未读邮件模型中去,然后将该模型传递给邮件接收和保存方法,该方法将会对邮件在硬盘中进行保存,并更新客户端配置信息中得未读邮件信息。

3.2 系统模块的划分
按照本系统的总体功能划分,可以将这个电子邮件客户端分成5大模块,首先是登录模块,作为验证需要;其次是接收邮件模块,该模块负责邮件的接收,再次是发送模块,该模块负责该对方发送邮件;接着是邮件处理模块,该模块负责邮件的阅读、保存等操作;然后是邮件账户的管理,该操作负责设置客户端对公网的身份标识。

图3.2给出了本系统的模块体系:
图3.2 系统模块体系图
第4章详细设计
4.1 接收邮件模块
接收邮件模块主要由接收邮件线程监听端口完成对邮件的接收并对其进行保存和刷新主界面,包括下图中的几个部分。

(1)接收邮件线程。

一个邮件系统最基本的功能是能够接受发送的邮件。

为了可以同时接收多个邮件,保持并发性,本设计使用java多线程的功能,设计一个可以多线程的接收邮件线程;
(2)保存邮件。

接收到对方的邮件以后,必须先对邮件进行保存备份,然后将邮件信息封装到未读邮件模型后,再显示出来,可以隐去一些不必要的内容,只显示邮件关键信息给用户;
(3)刷新界面。

当客户端收到一个邮件后,必须能够实时刷新主界面以提醒用户。

接收邮件和附件模块的图示:
图4.1 接收邮件和附件模块图
4.2 发送和回复邮件模块
发送邮件模块主要由发送邮件线程文件完成,包括图中的几个部分。

(1)编写新邮件。

该部分也是电子邮件系统中最基本的功能。

(2)发送新邮件。

在编写完成新邮件后,电机该功能将邮件内容发送给对方。

发送邮件模块的图示:
图4.2 发送邮件模块图
4.3 邮件处理模块
邮件处理模块主要对邮件进行阅读和保存功能,包括图中的几个部分。

(1)显示邮件内容,新建一个界面显示用户选择的邮件内容。

(2)保存邮件。

在接收到邮件的同时,默认自动保存邮件。

(3)显示错误信息。

在出现一些登录错误,删除错误,发送错误时,将显示不同的错误信息提示用户。

邮件处理模块的图示:
图4.3 邮件处理模块图
4.4 界面实现的流程图
如上所述,本设计的邮件客户端需要六个不同的界面,都采用java swing 技术实现,java swing提供丰富的图形组件和多样的布局方式,以及事件注册处理机制,在本设计中使用java swing技术实现这些界面,其流程如图4.4所示:
图4.4 界面实现流程图
其中的部分代码如下:
……
buttonPanel.add(newButton);
buttonPanel.add(recButton);
buttonPanel.add(recboxButton);
buttonPanel.add(draftButton);
buttonPanel.add(setButton);……
jFrame.setBounds(0, 0, SCREEN_WIDTH*3/4,SCREEN_HEIGHT*3/5);
jFrame.setBackground(Color.WHITE);
jFrame.add(buttonPanel,new BorderLayout().WEST);
jFrame.add(tab,new BorderLayout().CENTER);
jFrame.setVisible(true);……
4.5 邮件发送过程的流程图
邮件发送过程需要使用SMTP协议,因此在本设计中,将SMTP协议的各个字段封装到了一个对象中去,便于维护和管理,邮件发送的实现过程如图4.5所示,其部分实现代码如下
……
String destip =
getEmailNameInfo.getusername(username).replace("_", ".");
socket = new Socket(destip,PORT);
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
sendAndReceive(null,br,pw);
if(sendResult.equals(FAILED)){
JOptionPane.showMessageDialog(MainUI.jFrame, "连接邮件服务器失败!",null, 0);return;}
sendAndReceive(smtp.getMail(), br, pw);
if(sendResult.equals(FAILED)){return;}
sendAndReceive(smtp.getRept(), br, pw);
if(sendResult.equals(FAILED)){return;}
sendAndReceive(smtp.getData(), br, pw);
if(sendResult.equals(FAILED)){return;}
sendAndReceive(message.getFrom()+"\r\n"+message.getTo()+"\r\n"+me ssage.getData(), br, pw);
if(sendResult.equals(FAILED)){
JOptionPane.showMessageDialog(MainUI.jFrame, "邮件发送失败!",null, 0);return;}
sendAndReceive(smtp.getQuit(), br, pw);
if(sendResult.equals(FAILED)){
JOptionPane.showMessageDialog(MainUI.jFrame, "邮件发送成功!",null, 0);return;}
图4.5 邮件发送过程
其中邮件发送过程分为如下几步:
1、发送HELO命令,并等到回复,若回复争取,则发送下一个命令,若
失败停止发送,下面步骤皆是如此处理;
2、发送EHLO命令;
3、发送 auth login命令,进行用户名和密码的鉴权请求;
4、发送BASE64加密后的用户名;
5、发送BASE6加密后的密码;
6、若鉴权成功发送mail from命令;
7、发送rcpt to命令,告知服务器邮件的接收方;
8、发送data命令,告知服务器接下来要发送邮件内容;
9、在本设计中邮件内容被封装到一个Message模型中,在本步中,发送的是该模型的一个对象;
10、在收到成功响应后,发送“.”结束发送过程。

4.6 邮件接收流程
邮件接收流程是该设计的基本功能之一,其使用的仍是SMTP协议流程,在本设计中,针对收到的邮件会将其封装到一个未读邮件的对象中去,具体流程如图4.6所示,其部分代码如下所示:
图4.6 邮件接收流程
while((request = br.readLine())!=null){
if(request.contains("mail from:") && request.contains("@") && request.contains(".com")
|| request.contains(".cn")){
isMAILFROM = true;
pw.println("250 sender ok");
continue;
}else if(!isMAILFROM){
pw.println("500 command not recognized");
continue;}
if(request.contains("rcpt to:") && request.contains("@") && request.contains(".com")
|| request.contains(".cn")){
isRCPTTO = true;
pw.println("250 recipient ok");
continue;
}else if(!isRCPTTO){
pw.println("500 command not recognized");
continue;}
if(request.contains("data")){
isDATA = true;
pw.println("354 enter content");
continue;
}else if(!isDATA){
pw.println("500 command not recognized");
continue;}
if(isDATA){
stringBuffer.append(request);
stringBuffer.append(".");
if(stringBuffer.toString().endsWith("..")){
isMessage = true;
content = stringBuffer.toString().substring(0, stringBuffer.toString().length()-1);
System.out.println("content is "+content);
pw.println("250 ok");}}
if(request.contains("quit")){
pw.println("221
"+getEmailNameInfo.getHostname(e_mailConfig.getEmailCFG().getEmailnam e()));return;}}
private PrintWriter getWriter(Socket socket) throws IOException { // TODO Auto-generated method stub
OutputStream out = socket.getOutputStream();
return new PrintWriter(out, true);
}
private BufferedReader getReader(Socket socket) {
InputStream is = null;
try {
is = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();}
BufferedReader br = new BufferedReader(new
InputStreamReader(is));
return br; }
4.7 用户鉴权和客户端配置信息流程
该模块是在主界面加载前,针对不同的用户,加载相应的设置,其包含保存用户信息流程,更改用户信息流程,保存邮箱账户信息流程,更改邮箱账户信息流程,获取收到的邮件信息流程,设置邮件是否已读流程。

其中这三组流程处理方式一致,获取和更改用户信息流程如图4.7,4.8所示,部分处理代码如下。

4.7获取用户信息流程 4.8 更改用户信息流程图
protected User getUserProfile(){
User user = new User();
SAXBuilder builder = new SAXBuilder();
try
{Document doc = builder.build(USERFILE);
Element rootElement = doc.getRootElement();
String username = rootElement.getChild(USERNAME).getText();
user.setUsername(username);
String password = rootElement.getChild(PWD).getText();
user.setPassword(password);
boolean login = new
Boolean(rootElement.getChild(LOGIN).getText());
user.setLogin(login);}
catch(Exception e){
e.printStackTrace();}
return user;}
protected void setUserProfile(User user){
SAXBuilder builder = new SAXBuilder();
try{ Document doc = builder.build(USERFILE);
Element rootElement = doc.getRootElement();
rootElement.getChild(USERNAME).setText(user.getUsername());
rootElement.getChild(PWD).setText(user.getPassword());
rootElement.getChild(LOGIN).setText(String.valueOf(user.isLogin() ));
XMLOutputter fmt=new XMLOutputter();
FileWriter writer=new FileWriter(USERFILE);
org.jdom.output.Format f =
org.jdom.output.Format.getPrettyFormat();
fmt.setFormat(f);
fmt.output(doc, writer);
writer.close();}
catch(Exception e){
e.printStackTrace();}}
4.8 阅读邮件流程
邮件阅读是邮件系统的最基本功能之一,在本设计中,邮件阅读流程如图4.9所示,其代码如下
String isread = String.valueOf(array.get(index-1).isRead());
String name = array.get(index-1).getName();
int length = name.length();
int sindex = name.indexOf("_");
user = name.substring(0, sindex);
String rest = name.substring(sindex+1, length);
int index2 = rest.indexOf("_");
topic = rest.substring(0,index2);
File file = new File(name+".txt");
in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
StringBuffer sb = new StringBuffer(); String string = null;
while((string=in.readLine())!=null){ sb.append(string);
}
string = sb.toString();
BaseMain.setUnReadMail(user); showcontent(string);
图 4.9 邮件阅读流程
第5章系统功能测试
5.1 登陆界面及邮箱账户设置界面测试
界面模块主要使用java swing技术完成,其中包括主界面,登陆界面,设置账户界面,阅读邮件界面,发送邮件界面等几部分。

登陆选择指定邮件用户和密码。

在本系统中提供了一个用户名和密码均为admin的默认用户进行登录。

使用默认用户登录后,用户可以更改登录账户。

必须使用正确的用户名和密码才可以登录,不然无法进入客户端。

登录界面的效果图:
图5.1 登录界面
设置账户界面用来标识对公网的客户端身份,只有设置正确存在的公网账户才可以使用本客户端对外发送邮件。

设置账户界面效果图:
图5.2 邮箱账户设置界面
5.2 主界面测试
主界面是客户端与用户交互的直接体现,它调用相应的界面和方法响应用户的操作,主界面见图5.3;
图5.3 主界面
5.3 发送界面与收件箱界面测试
发送界面是发送邮件时的操作控制界面,主要有设置接收人,抄送,密送,
邮件主题,邮件内容等5部分组成,发送界面见图5.4
图5.4 发送邮件界面
收件箱界面是登陆客户端时由邮箱配置方法将收到邮件信息设置在它下面,在主界面选择它后,即可查看客户端收到的邮件信息情况,收件箱界面见图5.5;
图5.5 收件箱界面
5.4 阅读邮件界面测试
阅读邮件界面是根据在收件箱界面的列表,选择一条未读邮件后,进行未读邮件内容的显示,阅读邮件界面见图5.6;
图5.6 阅读邮件界面
第6章结论与展望
6.1 结论
系统主要实施对于邮件系统中邮件及邮件夹的管理。

系统主要实现了对于邮件的发送、接收、删除、邮件夹的管理等功能。

6.2 展望
系统开发是需要一个不断完善的过程,通过不断测试,检测出更多问题,并不断完善。

然而由于时间的缘故,并不能进行逐步测试,因此仍然有很多地方需要改进。

现在归纳如下:有时候邮件太长,或者是表格、Word文档,一正文方式发送不太方便,这样可以引用一个附件功能。

及那个这些表格或Word文档以附件的形式上传,然后发送。

在扩充一下,提供可以发送多个邮件的功能。

但本系统未实现此功能。

致谢
感谢我的指导老师彭晓天老师,本次论文的每个细节和每个数据,都离不开他的细心指导。

无论在理论上还是在实践中,彭老师都给了我很大的帮助,使我得到不少的提高这对于我以后的工作和学习都有一种巨大的帮助。

另外,在系统开发过程中同学也给予我很大的帮助,帮助解决了不少的难点,使得系统能及时开发完成,这里一并表示感谢。

在论文即将完成之际,我的心情无法平静,从开始进入课题到论文的顺利完成,有许多可敬的师长、同学、朋友给了我无私的帮助,在这里请接受我诚挚的谢意!
参考文献
[1]张尧学等编著,计算机网络与Internet教程(第三版).北京:清华大学出版社,2001
[2]Computer Networks,Version Prentice Hall International,Inc.1998(《计算机网络》第四版,清华大学出版社影印版,2001)。

[3]Internetworking with TCP/IP(Vol.1,Vol.2,Vol.3) Prentice Hall International,Inc.1995(《TCP/IP网络互连技术》卷1、卷2、卷3,清华大学出版社影印版,1998)。

[4]谢希仁主编,《计算机网络》(第三版),北京:电子工业出版社,2000。

附录
1、主界面主要代码
public class MainUI extends BaseMain{
@SuppressWarnings("unused")
private static String title;
private User user;
private boolean isFirstLogin = false;
public static JFrame jFrame;
public static final String WELCOME_WORD01 = "欢迎使用邮件客户端",WELCOME_WORD02 = "作者 : 党西娇
",WELCOME_WORD03 = "班级 : 通信 901";
public static final String NEW= "写信",RECEIVED= "收信",RECBOX = "收件箱",DRAFT = "草稿",SET = "设置";
public static final int BUTTON_NUMBER = 20,BUTTON_WIDTH =
30,BUTTON_HEIGHT = 20,BUTTON_START_POINT = 0;
public static int DRAFT_EMAIL = 0;
public static JButton newButton,recButton,recboxButton,
contactButton,unreadButton,raftButton, sendButton,deleteButton, rabishboxButton,setButton;
public static JTabbedPane tab;
public static JPanel buttonPanel,sendPanel;
public Color[] colorStyle = new
Color[]{Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY, Color.GRAY,Color.GREEN,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANG E,Color.PINK,Color.YELLOW,Color.RED};
public JLabel start01,start02,start03;
public JPanel labelPanel;
public static final String DEFAULT_FONT = "宋体";
public static int UNREADNUMBER =
getUnreadCounter(BaseMain.getUnReadMailNumber());
public static int DELETEDNUMBER = 1;
private static boolean flag = false;
private JPanel tempPanel;
public MainUI(String title){
this.title = title;
}
public void start(){
initButton();
initTable();
user = getUserProfile();
isFirstLogin = user.isLogin();
show(isFirstLogin);
}
public void initButton() {
// TODO Auto-generated method stub
newButton = new JButton(NEW);
newButton.setContentAreaFilled(false);
newButton.setBackground(Color.WHITE);
newButton.setForeground(Color.BLUE);
newButton.addActionListener(listener);
newButton.setBounds(BUTTON_START_POINT, BUTTON_START_POINT, BUTTON_WIDTH, BUTTON_HEIGHT);
……
buttonPanel = new JPanel();
buttonPanel.setBackground(Color.WHITE);
buttonPanel.setLayout(new GridLayout(BUTTON_NUMBER, 0,0,0));
buttonPanel.add(newButton);
buttonPanel.add(recButton);
buttonPanel.add(recboxButton);
buttonPanel.add(draftButton);
buttonPanel.add(setButton);}
public void initTable() {
// TODO Auto-generated method stub
tab = new JTabbedPane(JTabbedPane.TOP);
tab.setBackground(Color.WHITE);
tab.addMouseListener(mListener);
start01 = new JLabel();
……
start01.setBackground(Color.WHITE);
……
start01.setText(WELCOME_WORD01);
……
start01.setHorizontalAlignment(SwingConstants.CENTER);
……
labelPanel = new JPanel();
labelPanel.setBackground(Color.WHITE);
labelPanel.setLayout(new GridLayout(3, 0, 4, 4));
labelPanel.add(start01);
labelPanel.add(start02);
labelPanel.add(start03);
tab.add("主页",labelPanel);
new Thread(new changeColor()).start();}
@SuppressWarnings("static-access")
public void show(boolean isFirstLogin){
jFrame = new JFrame();
jFrame.setBounds(0, 0, SCREEN_WIDTH*3/4,SCREEN_HEIGHT*3/5);
jFrame.setBackground(Color.WHITE);
jFrame.add(buttonPanel,new BorderLayout().WEST);
jFrame.add(tab,new BorderLayout().CENTER);
jFrame.setVisible(true);
if(!isFirstLogin){
jFrame.setFocusable(false);
jFrame.setEnabled(false);
new Login_UI(new MainUI());}
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ReceiveEmail.isRunning = false;}
private ActionListener listener = new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals(NEW)){
SendUI sendUI = new SendUI(new MainUI());
sendPanel = sendUI.initSendUI();
tab.add(NEW,sendPanel);
tab.setSelectedComponent(tempPanel);
}else if(e.getActionCommand().equals(SET)){
new SetUI(new MainUI());
}else if(e.getActionCommand().contains(RECBOX) ||
e.getActionCommand().equals(RECEIVED)){
if(!flag){
ReceivedUI receiveUI = new ReceivedUI(new MainUI());
tempPanel = receiveUI.initrecvUI();
tab.add(RECBOX,tempPanel);
tab.setSelectedComponent(tempPanel);
flag = true;
}else{
tab.setSelectedComponent(tempPanel);}}}};
private MouseListener mListener = new MouseListener() {
……
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(e.getClickCount() == 2){
if(tab.getSelectedComponent()!=labelPanel){
if(tab.getSelectedComponent().equals(tempPanel)){
flag = false;}
tab.remove(tab.getSelectedComponent());}}}};
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new ReceiveEmail()).start();
new MainUI("E_main Client").start();}
class changeColor implements Runnable{
public void run() {
int colorlength = colorStyle.length;
for(int j=0;j<colorlength;j++){
start01.setForeground(colorStyle[j]);
……
try {Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();}
if(j == colorlength -1){j = 0;}}}}}
2、发送邮件界面
package com.dangxijiao.Email.UI;
public class SendUI {
private static final int COLUMNS = 70;
private static final String SEND="发送",DRAFT="存草稿";
CANCEL="取消",reciver="收件人",cc="抄送",sc="密送",topic="主题";
private JButton sendButton,draftButton,cancelButton;
private JLabel reciverLabel, ccLabel, scLabel, topicLabel;
public static JTextField reciverField,ccField,scField,topicField;
private JTextArea contentArea;
private JPanel returnPanel;
public SendUI(MainUI mainUI){
}
protected JPanel initSendUI(){
returnPanel = new JPanel();
int width = BaseMain.SCREEN_WIDTH;
int height = BaseMain.SCREEN_HEIGHT;
returnPanel.setBounds(30, 10,width-30, height-10);
returnPanel.setBackground(Color.WHITE);
returnPanel.setLayout(new BorderLayout());
sendButton = new JButton(SEND);
sendButton.setBackground(Color.WHITE);
sendButton.setForeground(Color.BLUE);
sendButton.addActionListener(listener);
……
JPanel buttonPanel = new JPanel();
buttonPanel.setBackground(Color.WHITE);
buttonPanel.setLayout(new GridLayout(0,8,20,0));
buttonPanel.add(sendButton);
buttonPanel.add(draftButton);
buttonPanel.add(cancelButton);
reciverLabel = new JLabel(reciver);
reciverField = new JTextField(COLUMNS);
reciverField.setHorizontalAlignment(JTextField.LEFT);
JPanel reciverPanel = new JPanel();
reciverPanel.setBackground(Color.WHITE);
reciverPanel.setLayout(new FlowLayout());
reciverPanel.add(reciverLabel);
reciverPanel.add(reciverField);
……
JPanel jPanel = new JPanel();
jPanel.setBackground(Color.WHITE);
jPanel.setBounds(30, 10, width-30, 50);
jPanel.setLayout(new GridLayout(5, 0, 0, 2));
jPanel.add(reciverPanel);
jPanel.add(ccPanel);
jPanel.add(scPanel);
jPanel.add(topicPanel);
jPanel.add(buttonPanel);
contentArea = new JTextArea();
contentArea.setWrapStyleWord(true);
contentArea.setLineWrap(true);
JScrollPane jscrollPane = new JScrollPane(contentArea);
returnPanel.add(jPanel,BorderLayout.NORTH);
returnPanel.add(jscrollPane,BorderLayout.CENTER);
return returnPanel;
}
private ActionListener listener = new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals(SEND)){
……
}
};
}
3、主界面加载前的方法类
package com.dangxijiao.Email.UI;
public class BaseMain {
protected static final String USERFILE = "user_profile.xml";
EMAILFILE= "unreademail.xml",USERNAME= "username",PWD= "password";
LOGIN = "login",NAME="name",TIME="time",READ="read";
protected User getUserProfile(){
User user = new User();
SAXBuilder builder = new SAXBuilder();
try
{
Document doc = builder.build(USERFILE);
Element rootElement = doc.getRootElement();
String username = rootElement.getChild(USERNAME).getText();
user.setUsername(username);
String password = rootElement.getChild(PWD).getText();
user.setPassword(password);
boolean login = new
Boolean(rootElement.getChild(LOGIN).getText());
user.setLogin(login);
}
catch(Exception e){
e.printStackTrace();
}
return user;
}
protected void setUserProfile(User user){
SAXBuilder builder = new SAXBuilder();
try
{
Document doc = builder.build(USERFILE);
Element rootElement = doc.getRootElement();
rootElement.getChild(USERNAME).setText(user.getUsername());
rootElement.getChild(PWD).setText(user.getPassword());
rootElement.getChild(LOGIN).setText(String.valueOf(user.isLogin() ));
XMLOutputter fmt=new XMLOutputter();
FileWriter writer=new FileWriter(USERFILE);
org.jdom.output.Format f =
org.jdom.output.Format.getPrettyFormat();
fmt.setFormat(f);
fmt.output(doc, writer);
writer.close();
}
catch(Exception e){
e.printStackTrace();
}
}
protected static ArrayList<UnreadEmail> getUnReadMailNumber(){ ArrayList<UnreadEmail> array = new ArrayList<UnreadEmail>();
int index = 0;
SAXBuilder builder = new SAXBuilder();
try
{
…//类似getUserProfile()
}catch(Exception e){}
}
protected static int getUnreadCounter(ArrayList<UnreadEmail> arrayList){
int result = 0;
int length = arrayList.size();
System.out.println(length);
for(int j=0;j<length;j++){
System.out.println(arrayList.get(j).getName()+" "+j);
if(!arrayList.get(j).isRead()){
result++;
}
}
return result;
}
@SuppressWarnings("unchecked")
protected static void setUnReadMail(String username){
SAXBuilder builder = new SAXBuilder();
try
{
……//类似setUserProfile
}
catch(Exception e){
e.printStackTrace();
}
}
protected static final int SCREEN_WIDTH =
Toolkit.getDefaultToolkit().getScreenSize().width;
protected static final int SCREEN_HEIGHT =
Toolkit.getDefaultToolkit().getScreenSize().width;
}
4、BASE64加密方法
package com.dangxijiao.Email.Utils;
public class Base64 {
private static char[] base64EncodeChars = new char[]{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
public static String Encoding(String str){
StringBuffer sb = new StringBuffer();
byte[] content = str.getBytes();
int length = content.length;
int i=0,temp01=0,temp02=0,temp03=0;
while (i < length) {
temp01 = content[i++] & 0xff;
if (i == length) {
sb.append(base64EncodeChars[temp01 >>> 2]);
sb.append(base64EncodeChars[(temp01 & 0x3) << 4]);
sb.append("==");
break;
}
temp02 = content[i++] & 0xff;
if (i == length) {
sb.append(base64EncodeChars[temp01 >>> 2]);
sb.append(base64EncodeChars[((temp01 & 0x03) << 4) | ((temp02 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[(temp02 & 0x0f) << 2]);
sb.append("=");
break;
}
temp03 = content[i++] & 0xff;
sb.append(base64EncodeChars[temp01 >>> 2]);
sb.append(base64EncodeChars[((temp01 & 0x03) << 4) | ((temp02 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[((temp02 & 0x0f) << 2) | ((temp03 & 0xc0) >>> 6)]);
sb.append(base64EncodeChars[temp03 & 0x3f]);
}
return sb.toString();
}
}
5、发送邮件方法
package com.dangxijiao.Email.Method;
public class SendProcess{
private static final String SUCCESS = "success",FAILED =
"failed",PREFIX = "smtp.";
private static final int PORT = 25;
private SMTP smtp;
private Email_Message message;
private String sendResult = null,hostname,username;
protected Socket socket = null;
public SendProcess(String username,SMTP smtp,Email_Message message,String hostname){
ername = username;
this.smtp = smtp;
this.message = message;
this.hostname = hostname;
}
public void start_send(){
String choice = getEmailNameInfo.getHostname(username);
if(choice.equals("")){
send_inner_email();
}else{
send_outter_email();
}
}
private void send_inner_email() {
// TODO Auto-generated method stub
try {
String destip =
getEmailNameInfo.getusername(username).replace("_", ".");
socket = new Socket(destip,PORT);
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
sendAndReceive(null,br,pw);
if(sendResult.equals(FAILED)){
JOptionPane.showMessageDialog(MainUI.jFrame, "连接邮件服务器失败!",null, 0);
return;。

相关文档
最新文档