概述:使用J2ME实现收发邮件,大部分都是采用Midlet+Servlet的组合,即J2ME程序使用HTTP协议与服务器上的Servlet通信,然后Servlet再负责连接WEB邮件服务器,进行邮件收发,其结构如下:
Cell Phone将请求(接受/发送邮件)传给Web Server,Web Server将这些http请求转换成对POP3或 SMTP Server的请求。POP3/SMTP Server执行相应的请求,并将相应通过Web Server返回给Cell Phone.
客户端(PDA/手机)为J2ME程序。MIDP2.0提供了一些基本网络连接的API。利用这些API可以使得J2ME程序可以向远端发出Http请求,并接受响应,传递数据流。MailAgent 为Servlet,用来接收来自客户端的请求,并调用Java Mail API,将这些请求转变成对远端Mail Server 的请求,同时将Mail Server的响应传给客户端。
采用这样的架构是因为MIDP2.0不支持POP3 和 SMTP等其它应用层协议,而J2EE提供了完整的Java Mail的API,所以考虑通过一个Servlet将Http请求转换成POP3或SMTP请求。
上面论述了Midlet + Servlet + Web mail server架构的原理和实现,但是由于需要采用Servlet进行中转通信,使用起来不太方便,因为手机的J2ME程序若想收发邮件,必须保证Servlet的运行。我们知道,MIDP2.0在MIDP1.0的基础上增加了对socket通讯的支持,是否可以在手机J2ME程序中直接使用socket连接到邮件服务器呢?答案当然是肯定的!不过由于CMWAP目前尚不能支持socket通信协议,只能采用CMNET接入方式连接到邮件服务器。
如此一来,用Midlet + Web mail server即实现了同样的功能,结构如下:
下面来说明具体实现过程:
一、发送邮件实现过程
发送邮件一般使用SMTP协议,具体步骤(红色文字应改为实际内容):
1、登录SMTP邮件服务器:
step1、使用MIDP的SocketConnection连接到目标SMTP邮件服务器地址(如smtp.163.com)25号端口。连接成功后打开其输入、输出流;
step2、发送"HELO/r/n",与服务器握手;
step3、发送"AUTH LOGIN/r/n",进入登录模式(准备输入用户名、密码);
step4、发送经过Base64编码后的用户名;
step5、发送经过Base64编码后的密码。
2、发送邮件头信息以及内容:
step1、发送发件人email地址,相应的SMTP协议命令格式为"MAIL FROM: < Sender email address >/r/n";
step2、发送收件人email地址,命令格式为"RCPT TO: < Recipient email address >/r/n";
step3、发送完整的邮件内容。格式如下:
"From: Sender email address /r/n"
"To: Recipient email address /r/n"
"Subject: Mail subject /r/n"
"/r/n"
" Mail content /r/n"
"."
"/r/n";
step4、发送完毕,根据SMTP服务器的回馈信息判断邮件是否发送成功。
二、接收邮件实现过程
接收邮件一般使用POP3服务器,但是POP3协议的命令非常有限,一般需要将POP3服务器上所有邮件(或邮件头信息)先下载到本地,这势必会造成较大的网络流量且涉及到数据库,不适于在手机上实现。
相对而言,IMAP协议则有更为丰富的接收邮件命令:可以获得邮箱未读邮件总数,未读邮件ID,邮件头信息中的特定内容(如发件人、时间、主题)等等,方便读取未读邮件以及最新邮件,这样即可大大减少手机的网络流量。目前支持IMAP服务的邮件服务器主要有Gmail、21cn、QQ等。下面是使用IMAP协议接收邮件的具体步骤(红色文字应改为实际内容):
1、登录IMAP邮件服务器:
step1、使用SocketConnection连接到目标IMAP邮件服务器地址(如imap.qq.com)的143号端口。连接成功后打开其输入、输出流;
step2、发送用户名、密码进行登录。命令格式为:"A1 LOGIN username password /r/n";
step3、选择邮箱文件夹,一般IMAP服务器的默认文件夹都是inbox,当然也可以自己新建或删除邮箱文件夹。命令格式:"A2 SELECT inbox/r/n";
2、收取指定邮件:
step1、查询邮箱状态,包括邮件总数、未读邮件总数等。
命令格式:"A3 STATUS inbox (messages unseen)";
step2、如果有未读邮件,查询所有未读邮件ID:"A4 SEARCH unseen";
step3、查询指定邮件大小:"A5 FETCH MailId RFC822.SIZE";
step4、收取指定邮件头,包括发件日期、发件人、邮件主题等。
命令格式:"A6 FETCH MailId body[header.fields (date from subject)]";
step5、根据邮件大小,判断是否收取邮件内容。如果邮件超过设定的大小限制,不进行取操作,以节省手机网络流量。
命令格式:"A7 FETCH MailId body[text]";
step6、邮件接收完毕,显示邮件内容。
备注:
上面所说的邮件收发过程只是我在自己程序中所做的处理,具体实现时完全可以参照SMTP/POP3/IMAP协议的相关命令进行灵活运用。