|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在ruby里才是一切皆对象。当然我不并不是很了解ruby,但是ruby确实是将语法简化得很好。程序在J2ME平台上构建你的邮件程序
JackyPan
TableofContents
1.教程的先容和程序的安装
2.程序的布局
3.界面的计划
4.账户的办理
5.MIDlet和Servlet的收集毗连
6.Servlet和JavaMail
7.复杂的XML
8.小结
1.教程的先容和程序的安装
本教程报告了怎样在J2ME平台上编写一个复杂的邮件使用程序,包含界面的计划,邮件的发送/承受,邮件账户的创立/修正/删除,背景Servlet的编写。
为了运转本教程所带的演示程序,您必要安装以下软件:
1.WTK2.0(java.sun.com)
2.ApacheTomcat(www.apache.org)
安装和运转示例程序的步骤:
1.从http://groups.yahoo.com/group/OriTec/files/下载MicroMailBeta.zip(包含了源代码和二进制文件)
2.解压MicroMailBeta.zip至$TMP
3.在$WTK/apps下建一新目次MicroMail
4.拷贝$TMP/src/client/*至$WTK/apps/MicroMail/src/
5.拷贝$/TMP/bin/server/mail.war至$TOMCAT/webapps/
6.运转Tomcat
7.运转WTK2.0,“OpenProject”并选中MicroMail
8.设置URL为MailAgent的地点http://server/mail/MailAgent
2.程序的布局
接纳Client-WebServer-MailServer三层架构,如。
MIDlet
(CellPhone)
Servlet
(WebServer)
MailServer
MyApplication
Figure1
CellPhone将哀求(承受/发送邮件)传给WebServer,WebServer将这些http哀求转换成对POP3或SMTPServer的哀求。POP3/SMTPServer实行响应的哀求,并将响应经由过程WebServer前往给CellPhone.
客户端(PDA/手机)为J2ME平台上的程序。MIDP2供应了一些基础收集毗连的API。使用这些API可使得J2ME程序能够向远端收回Http哀求,并承受呼应,传送数据流。
MailAgent为Servlet,用来吸收来自客户真个哀求,并挪用JavaMailAPI,将这些哀求变化成对远端MailServer的哀求,同时将MailServer的呼应传给客户端。
那末为何要接纳如许的架构了?这是由于MIDP2.0只撑持HTTP协定,而不撑持POP3和SMTP等别的使用层协定,而J2EE供应了完全的JavaMail的API,以是思索经由过程一个Servlet将Http哀求转换成POP3或SMTP哀求。另外一个缘故原由是,良多运营商大概只供应无限的收集会见的才能,而经由过程一个agent则供应了程序部署的天真性。
上面复杂先容一下源码的布局,在客户端,ui包中的类界说程序的用户界面,utility包中的类界说了数据库的操纵,收集的毗连,XML的剖析等,mail包中的类界说了邮件账户,邮件的头。
uipackage:
AccountForm.java
AccountsList.java
Confirm.java
ConfirmListener.java
MailMIDlet.java
MessageList.java
ProgressForm.java
SendMessage.java
WriteContent.java
utilitypackage:
DBOperator.java
HeadParser.java
NetAdapter.java
Networker.java
ParserListener.java
mailpackage:
MailAccount.java
MessageHead.java
服务器端只要一个文件MailAgent.java,包括了一个servlet,用来做midlet和邮件服务器的桥梁。
3.界面的计划
MIDP2.0供应了大批的API供开辟者创立和把持用户界面。在包javax.microedition.lcdui中供应了List,Form,TextBox,Alert等Screen组件,在Form中能够包括一系列Item,如ChoiceGroup,TextField,StringItem等。包中还供应了Command组件,和响应的Listener。
源文件ui/MailMIDlet.java界说了程序的出口和MicroMail的主页面。如主页面是一个List,显现了几个功效模块,包含增加账户,修正/删除账户,承受邮件,发送邮件。
Figure2
publicMailMIDlet()
{
display=Display.getDisplay(this);
/*创立List*/
mainList=newList("MicroMail0.1",Choice.IMPLICIT);
/*创立两个把持按钮OK和Exit*/
cmOK=newCommand("OK",Command.OK,1);
cmExit=newCommand("Exit",Command.EXIT,1);
/*向mainlist中增加内容*/
mainList.append("AddAccount",null);
mainList.append("EditAccount",null);
mainList.append("ReceiveMessage",null);
mainList.append("SendMessage",null);
/*为mainlist增加Command*/
mainList.addCommand(cmOK);
mainList.addCommand(cmExit);
/*MailMIDlet完成了CommandListener接口,能够作为监听器*/
mainList.setCommandListener(this);
……
}
经由过程AccountForm(源文件ui/AccountForm.java),用户能够增加和修正邮件账户,如。
Figure3aFigure3b
AccountForm包括了6个TextField,分离显现邮件账户的6个属性。account为账户名,也是账户的独一标识,不成重名。address为邮件的地点,如bill@ms.com。user,password是在邮件服务商注册的用户名和暗码。pop3,smtp是pop3服务器和smtp服务器的名字或地点。
privatevoidsetContent(MailAccountmacc)
{
account=newTextField("Account:","",20,TextField.ANY);
address=newTextField("Address;","",40,TextField.EMAILADDR);
user=newTextField("UserName:","",20,TextField.ANY);
password=newTextField("Password:","",20,TextField.PASSWORD);
pop3=newTextField("POP3Server:","",20,TextField.ANY);
smtp=newTextField("SMTPServer:","",20,TextField.ANY);
if(macc!=null)
{
account.setString(macc.accountName);
address.setString(macc.address);
user.setString(macc.username);
password.setString(macc.password);
pop3.setString(macc.POP3Server);
smtp.setString(macc.SMTPServer);
}
append(account);
append(address);
append(user);
append(password);
append(pop3);
append(smtp);
}
别的页面与AccountForm相似,在此不再赘述,请人人参照源代码和MIDPAPI的文档。
4.账户的办理
邮件账户的创立,修正,删除都触及到对数据纪录的存取。MIDP供应了一种叫做纪录办理体系(RecordManagementSystem)的机制来存储和会见数据。
javax.microedition.rms.RecordStore供应了一些API来操纵这个体系。静态办法openRecordStore用来翻开或创立一个RecordStore对象。办法addRecord,getRecord,deleteRecord,setRecord分离用来增加,会见,删除或修正RecordStore对象中的纪录。
utility/DBOperator.java中封装了这些办法,从而完成增加,修正,删除邮件账户的操纵。以增加帐户为例,上面的addRecord办法用来向RecordStore中增加一个纪录,同时把这个纪录所暗示的邮件账户加到一个accounts中,accounts是一个Vecotr,用来存储体系中以后的账户。参数str包括了账户的一切信息,如账户名,地点,用户名,暗码,pop3,smtp等,它们之间用空格离隔。
publicvoidaddRecord(Stringstr)
{
intid;
byte[]rec=str.getBytes();
Stringrecord=str;
try
{
/*向RecordStore中增加纪录*/
id=rs.addRecord(rec,0,rec.length);
/*同时把帐户增加到accounts向量中*/
MailAccountmailacc=MailAccount.createMailAccountFromString(id,str);
accounts.addElement(mailacc);
}
catch(RecordStoreExceptionrse)
{
rse.printStackTrace();
}
}
5.MIDlet和Servlet的收集毗连
MIDP的收集API在包javax.microedition.io中界说,个中HttpConnection供应了对HTTP协定的撑持。
在文件utility/Networker.java中经由过程挪用这些收集API完成了吸收以后信箱中邮件列表setMessageList,承受某一邮件的内容receiveMessage,发送邮件sendMessage等功效。以sendMessage为例。
publicvoidsendMessage(finalStringurl,finalStringformData)//sendamessage
{
/*创立新的历程*/
Threadt=newThread()
{
publicvoidrun()
{
HttpConnectionhttp=null;
byte[]data=formData.getBytes();
try
{
/*翻开并前往一个HTTP毗连*/
http=(HttpConnection)Connector.open(url);
......
/*设置HTTP哀求头*/
http.setRequestMethod(HttpConnection.POST);
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setRequestProperty("User-Agent",
"Profile/MIDP-1.0Configuration/CLDC-1.0");
http.setRequestProperty("Content-Language","en-US");
http.setRequestProperty("Accept","application/octet-stream");
http.setRequestProperty("Connection","close");//optional
http.setRequestProperty("Content-Length",Integer.toString(data.length));
......
/*翻开输入流*/
OutputStreamos=http.openOutputStream();
/*写邮件数据*/
os.write(data);
/*封闭输入流*/
os.close();
}
catch(IOExceptionioe)
{
......
}
finally
{
try
{
/*封闭毗连*/
if(http!=null)http.close();
}
catch(IOExceptionignored){}
}
}
};
/*启动历程*/
t.start();
}
MIDlet经由过程HTTP毗连向Servelet收回承受或发送邮件的哀求,Servlet依据分歧的哀求向邮件服务器收回响应的哀求,并将前往了局传给MIDlet。
6.Servlet和JavaMail
J2EE中供应了对邮件相干协定的撑持,包javax.mail和包javax.mail.internet中界说了JavaMailAPI。上面是MailAgent.java中Servlet处置承受邮件列表哀求的代码片段。
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException
{
PrintWriterout=response.getWriter();
StringtypeStr=request.getParameter("type");
inttype=Integer.parseInt(typeStr);
Stringpop3Server;
Stringusername;
Stringpassword;
Propertiesprops;
Stringprovider;
switch(type)
{
caseRECEIVE_LIST:
/*提取参数pop3服务器,用户名,暗码*/
pop3Server=request.getParameter(paramPOP3);
username=request.getParameter(paramName);
password=request.getParameter(paramPass);
if(pop3Server==null||username==null||password==null)
{
out.print(STATUS_BAD);//xml?
return;
}
props=newProperties();
provider="pop3";
try
{
/*以指定的用户名和暗码毗连pop3服务器*/
Sessionsession=Session.getDefaultInstance(props,null);
Storestore=session.getStore(provider);
store.connect(pop3Server,username,password);
/*失掉INBOX收件箱*/
Folderinbox=store.getFolder("INBOX");
if(inbox==null)
{
out.print(STATUS_BAD);//xml?
return;
}
/*翻开收件箱*/
inbox.open(Folder.READ_ONLY);
/*失掉收件箱中的邮件列表,并写到XML中*/
writeXML(inbox.getMessages(),out);
inbox.close(false);
store.close();
}
catch(Exceptione)
{
out.println(e.getMessage());
e.printStackTrace();
}
out.close();
break;
caseRECEIVE_MESSAGE:
......
break;
caseSEND_MESSAGE:
......
break;
}
}
J2EE程序的编译和部署请人人参拍照关的书本或文档。http://www.tusc.com.au/tutorial/html/的<<TutorialforbuildingJ2EEApplicationsusingJBOSSandECLIPSE>>是一篇不错的文档。
7.复杂的XML
在MIDlet承受邮件时,起首向Servlet哀求传送邮箱中以后邮件的列表。列表中包含了邮件的头部信息,包含发送者的地点,邮件的主题,发送的工夫等,如。
Figure4
在邮件主题中大概包含任何字符,以是没有举措用某一特别字符分开这些信息,而XML恰好合适传输这类具有特定格局的信息。在Servlet端,把有效的邮件头部信息作为XML的元素写到输入流中。
privatevoidwriteXML(Message[]messages,PrintWriterout)
{
out.println("<?xmlversion="1.0"?>");
out.println("<mail>");
if(messages==null)
{
out.println("<error>NoMail</error>");
}
try
{
intj=0;
for(inti=messages.length-1;i>=0;i--)
{
out.println("<message>");
/*写邮件头*/
out.println("<from><![CDATA["+InternetAddress.toString(messages[i].getFrom())+"]]></from>");
out.println("<subject><![CDATA["+messages[i].getSubject()+"]]></subject>");
out.println("<date>"+messages[i].getSentDate().toLocaleString()+"</date>");
out.println("<index>"+i+"</index>");
out.println("</message>");
j++;
if(j>9)
{
/*一次只看10个邮件*/
break;
}
}
}
catch(MessagingExceptionme)
{
out.println("<error>"+me.toString()+"</error>");
}
out.println("</mail>");
}
在MIDlet端再剖析这个XML,在J2ME平台上有很多收费的XMLParser,kxml就是个中的一个。能够从http://kxml.enhydra.org/下载kXML1.21的源代码,jar文件和API文档。
上面是utility/HeadParser.java中处置XML的代码片段
publicvoidparse(InputStreamin)throwsIOException
{
Readerreader=newInputStreamReader(in);
XmlParserparser=newXmlParser(reader);
ParseEventpe=null;
parser.skip();
/*读一个名字为mail的event*/
parser.read(Xml.START_TAG,null,"mail");
booleantrucking=true;
booleanfirst=true;
while(trucking)
{
/*读取下一个event*/
pe=parser.read();
if(pe.getType()==Xml.START_TAG)
{
/*失掉event的名字*/
Stringname=pe.getName();
if(name.equals("message"))
{
Stringfrom=null;
Stringsubject=null;
Stringdate=null;
intindex=-1;
while((pe.getType()!=Xml.END_TAG)||
(pe.getName().equals(name)==false))
{
pe=parser.read();
if(pe.getType()==Xml.START_TAG&&
pe.getName().equals("subject"))
{
pe=parser.read();
/*失掉event的内容*/
subject=pe.getText();
}
elseif(pe.getType()==Xml.START_TAG&&
pe.getName().equals("from"))
{
pe=parser.read();
from=pe.getText();
}
elseif(pe.getType()==Xml.START_TAG&&
pe.getName().equals("date"))
{
pe=parser.read();
date=pe.getText();
}
elseif(pe.getType()==Xml.START_TAG&&
pe.getName().equals("index"))
{
pe=parser.read();
index=Integer.parseInt(pe.getText());
}
}
/*把邮件头交给监听器处置*/
headListener.itemParsed(from,subject,date,index);
}
else//NonMessageblock
{
while((pe.getType()!=Xml.END_TAG)||
(pe.getName().equals(name)==false))
pe=parser.read();
}
}
if(pe.getType()==Xml.END_TAG&&
pe.getName().equals("mail"))
{
trucking=false;
}
}
详细的API的用法请人人参照kxml的文档。JSR172(J2MEWebServicesSpecification)提出了在J2ME平台上处置XML的标准,有乐趣的伴侣能够到jcp的网站(http://www.jcp.org)上看看,但今朝大概还没有厂商或构造的完成。
8.小结
本文先容了J2ME平台上邮件程序的编写,触及的常识点有:
1.J2ME的UI
2.RecordStore
3.J2ME的收集毗连/J2ME和J2EE之间数据的传送
4.ParsingXMLinJ2ME
5.复杂的Servlet
6.JavaMailAPIs
参考材料有:
1.MIDP2.0Spec,http://www.jcp.org
2.<<CoreJ2ME>>,http://www.corej2me.com/
3.<<J2MEinNutshell>>,http://www.oreilly.com
4.TutorialforbuildingJ2EEApplicationsusingJBOSSandECLIPSE,http://www.tusc.com.au/tutorial/html/
市场分额,java比asp高一点,因为C#是仿照java开发的,所以哦C#能做的java都能做到,但是java能做的,C#不一定都能做到。毕竟是抄袭吗。 |
|