J2ME编程实践之联网开发

分类: J2ME   出处:iocblog整理  更新时间:2008-08-12   添加到收藏  

  由于无线设备所能支持的网络协议非常有限,仅限于http,socket,udp等几种协议,不同的厂家可能还支持其他网络协议,但是,midp 1.0规范规定,http协议是必须实现的协议,而其他协议的实现都是可选的。因此,为了能在不同类型的手机上移植,我们尽量采用http作为网络连接的首选协议,这样还能重用服务器端的代码。但是,由于http是一个基于文本的效率较低的协议,因此,必须仔细考虑手机和服务器端的通信内容,尽可能地提高效率。

 

  以下载一则新闻为例,一个完整的HTTP GET请求过程如下:

 

  首先,用户通过点击某个屏幕的命令希望阅读指定的一则新闻,在commandAction事件中,我们初始化HttpWaitUI和显示数据的NewsUI屏幕:

public void commandAction(Command c, Displayable d) {

HttpWaitUI wait = new HttpWaitUI("http://192.168.0.1/news.do?id=1",

new NewsUI());

ControllerMIDlet.forward(wait);

}

  NewsUI实现DataHandler接口并负责显示下载的数据:

public class NewsUI extends Form implements DataHandler {

public void setData(DataInputStream input) throws IOException {

String title = input.readUTF();

Date date = new Date(input.readLong());

String text = input.readUTF();

append(new StringItem("Title", title));

append(new StringItem("Date", date.toString()));

append(text);

}

}

  服务器端只要以String, long, String的顺序依次写入DataOutputStream,MIDP客户端就可以通过DataInputStream依次取得相应的数据,完全不需要解析XML之类的文本,非常高效而且方便。

  需要获得联网数据的屏幕只需实现DataHandler接口,并向HttpWaitUI传入一个URL即可复用上述代码,无须关心如何连接网络以及如何处理用户中断连接。

  使用POST发送数据

  以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在 HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST一个表单。以下是IE发送一个登陆表单的POST请求:

POST http://127.0.0.1/login.do HTTP/1.0

Accept: image/gif, image/jpeg, image/pjpeg, */*

Accept-Language: en-us,zh-cn;q=0.5

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)

Content-Length: 28

\r\n

username=admin&password=1234

  要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST:hc.setRequestMethod(HttpConnection.POST);

  然后构造出HTTP正文:byte[] data = "username=admin&password=1234".getBytes();

  并计算正文长度,填入Content-Type和Content-Length:

hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

hc.setRequestProperty("Content-Length", String.valueOf(data.length));

  然后打开OutputStream将正文写入:OutputStream output = hc.openOutputStream();output.write(data);

  需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,需要自己动手编写这个encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响应,代码与GET一致,这里就不再详述。

  使用multipart/form-data发送文件

  如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。

  以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:

  hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");

  然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下:

--ABCD

Content-Disposition: form-data; name="title"

\r\n

Today

--ABCD

Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt"

Content-Type: text/plain

\r\n

<这里是1.txt文件的内容>

--ABCD--

\r\n

  请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于—— 7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。

  

[1] [2] [3] [4] 下一页


Tag: 联网开发