当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]开发MIDP联网应用程序

♦引言

在上讲中,我们介绍了如何利用RecordStore把数据保存在终端内。本讲,我们将阐述MIDPJAVA网络的相关功能。由于N800终端只能使用HTTP通信,所以我们将以HTTP为主要范例进行讲解。到目前为止,只能制作终端内的单机型应用程序,如果利用网络,连接网络服务器,那么就能够制作出多种应用程序。

1.利用网络

1.1.GenericConnectionFrameWork

J2ME应该能支持各种手机终端。由于终端不同其网络功能及文件I/O功能也迥然不同,网络和文件I/O关联的图书馆所需的条件也不同。

为了解决上述问题,JSME的CLDC采用了GenericConnectionframework。GenericConnectionframework拥有不同终端所需的省空间网络功能以及文件I/O功能。广泛应用J2SE的java.io和java.net包里的网络、文件I/O功能,并准备7个interface。这样,为能支持各种手机终端的通信功能,只限定interface,在每个手机终端上都能自由安装。不支持手机终端连接的实际安装不能进行。各种interface的说明如表1所示、层次结构如图1所示。

点击图片看大图

表1

图1

1.2.ConnectionInterface

Connectioninterface在GenericConnectionframework中是连接interface的基础interface。其他的连接interface是从Connectioninterface派生而来的。

1.3.Connector类

使用Connector类的static方法open(StringconnectString)入网。

Connectioncon=Connector.open("http://www.nec-mfriend.com/");

ex.1

例如、如ex.1所示,在open方法的自变量中输入“http://www.nec-mfiend.com/”,就可以实现与www.nec-mfriend.com服务器进行http通信。

而GenericConnectionframework的全部链接都是利用Connector类的open方法完成的。也就是说,即使链接类型不同,也能以同样的方法完成。J2ME由于这样的设计而拥有丰富的扩展性,对于上述新的装置它也配备了简单的支持系统。

按照下述形式指定Open方法的自变量。

{protocol}:[{target}][{params}]

在Protocol部分可以指定如下所示的Protocol。

表2

*N800不支持socket通信、数据电报通信,而N820支持socket通信。

在Target部分指定服务器的用户名、端口号和文件名等。若有必要的添加信息则在Params部分指定。

Open方法也可以指定其他的自变量。

staticConnectionopen(StringconnectString,intmode)

从connectString中制作Connection、打开链接,若要使用mode链接则需指定accessmode。在accessmode中,可以指定Connector.READ,Connector.READ_WRITE和Connector.WRITE,若不指定,则为Connector.READ_WRITE。在Protocol中不能指定accessmode时,则放弃IllegalArgumentException。

下表是其他Connector类的static方法。

1.4.HTTP通信

现在,我们对N800所支持的HTTP通信进行阐述。利用HTTP通信可以连接WEB服务器。例如,可以把手机终端难以处理的复杂问题交给WEB服务器处理,得出结果。HTTP通信采用MIDP方法作为标准,但是,采用MIDP作为基本方法的终端却不能进行HTTP通信,或者有很大的限制,这一点请注意。

为能在N800中使用HTTP通信需遵从以下规定。

•要实现MIDlet通信必须在JAD(ADF)文件中设定MIDlet-UseNetwork(参考3.JAD(ADF)文件)为YES。.

•最大发送量为10kbyte。

大于10kbyte时,超出部分被清除,小于10kbyte的数据才是有效的。

•最大接收量为100kbyte。

大于100kbyte时,超出部分被清除,小于100kbyte的数据才是有效的。

•连接处URL

从http://开始,包含http://,最多为512byte。不分大/小写。

HTTP通信由request和response两部分组成。从客户发出的request信息传到服务器,服务器接收request,返还response信息。

HTTP通信主要有下述三种request方式。

接下来,让我们试着用多种request与服务器进行通信。

1.5.利用GET

利用GET可以读取服务器上的文件。在使用GET之前,如下所示需在已完成的HttpConnection方法的setRequestMethod方法中,指定HttpConnection的static变数GET。

HttpConnectioncon=(HttpConnection)Connector.open("http://www.nec-mfriend.com/");

con.setRequestMethod(HttpConnection.GET);

ex.2

如下所示可以利用DataInputStream获取response。

Stringres="";

DataInputStreamin=con.openDataInputStream();

intinput;

while((input=in.read())!=-1){

res=res+(char)input;

}

in.close();

ex.3

以下实际是与服务器通信,获取html文件的sample。为简单介绍sample的操作,得把通信结果,即获取的html文件内容,输入控制台。因此,此sample是以在模拟器上面操作为前提的。

importjava.io.DataInputStream;

importjava.io.IOException;[!--empirenews.page--]

importjavax.microedition.io.Connector;

importjavax.microedition.io.HttpConnection;

importjavax.microedition.midlet.MIDlet;

importjavax.microedition.midlet.MIDletStateChangeException;

/**

*利用GET发送request的sample

*从控制台输出response

*/

publicclassGETTestextendsMIDlet{

/**

*访问服务器

*/

protectedvoidstartApp()throwsMIDletStateChangeException{

try{

HttpConnectioncon=(HttpConnection)Connector.open("http://www.nec-mfriend.com/en/");

//指定GET

con.setRequestMethod(HttpConnection.GET);

DataInputStreamin=con.openDataInputStream();

intinput;

while((input=in.read())!=-1){

System.out.print((char)input);

}

in.close();

//关闭链接

con.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

protectedvoidpauseApp(){

}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{

}

}

ex.4

实际操作后的结果。

1.6.利用HEAD

接下来介绍如何利用HEAD方法获取文件的header。多数情况下,在HTTPheader中,包含了文件种类、尺寸大小、文字编码、回复日期、request文件的最后修改时间、以及兑现期限的截止日期等。一般来讲,使用HEAD方法检查其是否对兑现内容进行了新信息的替换。

为使用HEAD,如下所示要在作成的HttpConnection的setRequestMethod方法中,指定HttpConnection的static变量HEAD。

HttpConnectioncon=(HttpConnection)Connector.open("http://www.nec-mfriend.com/en/");

con.setRequestMethod(HttpConnection.HEAD);

获取HEAD信息的方法。

表3

下面是利用getHeaderField方法和getHeaderFieldKey方法,获取全部header信息的sample。这个sample与刚才所介绍的一样,是以在模拟器上进行操作为前提而作成的,它只用于说明,实际操作还没有进行测定。由此获取的全部header信息内容将输入控制台。

importjava.io.IOException;

importjavax.microedition.io.Connector;

importjavax.microedition.io.HttpConnection;

importjavax.microedition.midlet.MIDlet;

importjavax.microedition.midlet.MIDletStateChangeException;

/**

*利用HEAD发送request的sample

*从控制台输出response

*/

publicclassHEADTestextendsMIDlet{

/**

*显示header信息

*/

protectedvoidstartApp()throwsMIDletStateChangeException{

try{

HttpConnectioncon=

(HttpConnection)Connector.open("http://www.nec-mfriend.com/en/");

//指定HEAD

con.setRequestMethod(HttpConnection.HEAD);

//取得关键的HTTPheader信息——成对的值

inti=0;

Stringmessage="";

Stringkey="";

Stringvalue="";

while((value=con.getHeaderField(i))!=null){

key=con.getHeaderFieldKey(i++);

message=message+key+":"+value+"n";

}

System.out.println(message);

//关闭链接

con.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

protectedvoidpauseApp(){

}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{

}

}

ex.5

实际操作后的结果如下所示。

图3

1.7.利用POST

为能利用POST发送request,要使用InputStream和OutputStream。用OutputStream向服务器发送数据,而InputStream则接收来自服务器的response。

用下述方法指定POST。

HttpConnectioncon=(HttpConnection)Connector.open("http://www.yahoo.com");

con.setRequestMethod(HttpConnection.POST);

ex.6

如下所示使用OutputStream在requeat信息中输入数据,使输入数据为(message=helloworld),而变量con是指定了POST的HttpConnection。

Stringmessage=乭message=helloworld乭;

DataOutputStreamdos=con.openDataOutputStream();

byte[]request=message.getBytes();

for(inti=0;i

dos.writeByte(request[i]);

}

dos.flush();

ex.7

下面实际是利用POST与服务器进行通信的sample。在这里,WEB服务器将转发利用POST发送的信息值,并接收最终结果response。接收的response内容将被输入控制台,请用模拟器进行确认。

importjava.io.DataInputStream;

importjava.io.DataOutputStream;

importjava.io.IOException;

importjavax.microedition.io.Connector;

importjavax.microedition.io.HttpConnection;

importjavax.microedition.midlet.MIDlet;

importjavax.microedition.midlet.MIDletStateChangeException;

/**

*利用POST发送request的sample[!--empirenews.page--]

*从控制台输出response

*/

publicclassPOSTTestextendsMIDlet{

/**

*利用POST送信息

*/

protectedvoidstartApp()throwsMIDletStateChangeException{

try{

HttpConnectioncon=(HttpConnection)Connector.open("http://localhost:8080/nec_server/servlet/ReverseServlet");

//指定POST

con.setRequestMethod(HttpConnection.POST);

//在request中输入数据

Stringmessage="message=helloworld";

DataOutputStreamdos=con.openDataOutputStream();

byte[]messageByte=message.getBytes();

for(inti=0;i

dos.writeByte(messageByte[i]);

}

dos.flush();

dos.close();

//接收response

DataInputStreamin=con.openDataInputStream();

intinput;

while((input=in.read())!=-1){

System.out.print((char)input);

}

in.close();

//关闭链接

con.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

protectedvoidpauseApp(){

}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{

}

}

ex.8

接下来介绍本次使用的SERVLETsample,作为服务器实际安装的例子。因为本讲座是MIDP讲座,所以关于SERVLET的详细说明就不再赘述,网上有许多这方面的信息,请大家参考Sun—http://java.sun.com/products/servlet/等网站。

importjava.io.IOException;

importjava.io.PrintWriter;

importjavax.servlet.ServletException;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

/**

*把接收的文字列进行转发的SERVLET

*/

publicclassReverseServletextendsHttpServlet{

/**

*处理postrequest

*/

protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseres)

throwsServletException,IOException{

//接收参数

Stringmessage=req.getParameter("message");

//转发文字

Stringreverse="";

for(inti=message.length();i>0;i--){

reverse=reverse+message.charAt(i-1);

}

//写response

PrintWriterout=res.getWriter();

out.write("

n");

 

 

 

out.write("

n");

 

 

 

out.write("

n");

out.write("n");

out.write("

n");

out.write("messageis"+message+"
n");

out.write("ReverseMessageis"+reverse+"n");

out.write("

n");

out.write("");

out.close();

}

}

ex.9

实际操作如下所示:

2

2.制作应用程序

现在,我们介绍如何实际制作利用HTTP通信的应用程序。这次增添了以前所作的泡泡龙游戏(BlockApplication)的内容,并把游戏结束的时间作成高低分一览表,由服务器管理。为了使程序更简单,还省略了与声音相关的操作。以下是内容改变前的sourcecode:

 

BlockApplication.java

BlockCanvas.java

给这个程序添加

•计算结束时间功能。

•向服务器发送时间表功能。

•从服务器接收最高分功能。

通过游戏或游戏结束时,显示出最高分。

为了计算Http通信和时间表,给实际变量添加以下变量:

//相关经过时间

privateintsecond=0;

privatelongstartMs;

//http通信类

privatefinalStringSERVER_URL=

"http://localhost:8080/nec_server/servlet/BlockScoreServlet";//服务器的UPL

privateString[]highscore=null;//最高分

ex.10

2.1.计算结束时间

为了计算结束时间,要记录游戏开始时的系统时间(startMs),以这个时间为准计算经过时间,如下画面所示:

/*****************************************

*计时器相关处理

*****************************************/

/**

*计算经过时间

*/

publicintgetSecond(){

return(int)((System.currentTimeMillis()-startMs)/1000);

}

ex.11

2.2.向服务器发送时间表,接收最高分

如上所述,游戏结束时显示最高分。但是,游戏结束时向服务器发送时间表,而通过游戏时不发送时间表,只显示最高分。[!--empirenews.page--]

为在通过游戏时显示最高分,要与服务器进行通信,由此获得最高分。这里,可以用我们介绍的HttpConnection,利用GET取得最高分。可以在游戏结束时使用以下方法。

/**

*与服务器进行通信,获取最高分。

*/

publicString[]getHighScore(){

String[]str=newString[5];

HttpConnectioncon=null;

DataInputStreamin=null;

try{

con=(HttpConnection)Connector.open(SERVER_URL);

//接收response

in=con.openDataInputStream();

intinput;

inti=0;

Strings="";

while((input=in.read())!=-1){

if((char)input==‘n‘){

str[i]=s;

i++;

s="";

continue;

}

s=s+(char)input;

}

}catch(IOExceptione){

e.printStackTrace();

}finally{

if(con!=null){

try{

con.close();

}catch(IOExceptione1){

e1.printStackTrace();

}

}

if(in!=null){

try{

in.close();

}catch(IOExceptione1){

e1.printStackTrace();

}

}

}

returnstr;

}

ex.12

下面是进行游戏时的操作。结束游戏时向服务器发送结束时间,即利用POST如下所示发送结束时间。然后,接收来自服务器的response最高分。可以在游戏结束时使用以下方法。

/**

*向服务器发送时间表,取得最高分

*/

publicString[]sendScore(){

String[]str=newString[5];

HttpConnectioncon=null;

DataOutputStreamout=null;

DataInputStreamin=null;

try{

con=(HttpConnection)Connector.open(SERVER_URL);

con.setRequestMethod(HttpConnection.POST);

out=con.openDataOutputStream();

//向服务器发送时间表

Stringmessage="score="+second;

byte[]messageByte=message.getBytes();

for(inti=0;i

out.writeByte(messageByte[i]);

}

out.close();

//接收response

in=con.openDataInputStream();

intinput;

inti=0;

Strings="";

while((input=in.read())!=-1){

if((char)input==‘n‘){

str[i]=s;

i++;

s="";

continue;

}

s=s+(char)input;

}

}catch(IOExceptione){

e.printStackTrace();

}finally{

if(con!=null){

try{

con.close();

}catch(IOExceptione1){

e1.printStackTrace();

}

}

if(out!=null){

try{

out.close();

}catch(IOExceptione1){

e1.printStackTrace();

}

}

if(in!=null){

try{

in.close();

}catch(IOExceptione1){

e1.printStackTrace();

}

}

}

returnstr;

}

ex.13

2.3.显示最高分

通过游戏和游戏结束时,都显示最高分。用以下方法显示最高分:

/**

*显示最高分

*/

publicvoidpaintHighScore(Graphicsg){

for(inti=0;i

if(highscore[i]==null)break;

g.drawString(

highscore[i],

10,

10+i*15,

Graphics.LEFT|Graphics.TOP);

}

}

ex.14

2.4.运行

完成的sourcecode如下:

•BlockApplication.java

•BlockCanvas.java

另外,服务器使用的SERVLET的sourcecode式如下:

•nec_server.zip

运行后的结果如下:

3.总结

本讲中,介绍了可以利用HTTP通信进行网络编程。利用本讲介绍的东西,能够制作简单的chat程序以及联网作战游戏等应用程序。请大家也试着制作一些新的独特的应用程序吧。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭