随着越来越多手提电话和个人数字助理开始融入到信息高速公路之上,从移动设备上访问Web站点变得越来
越重要。Java开创了消费设备中小型的储存容量的先河,它是用于开发手机、传呼机及其他微型设备应用程序
的理想语言。
在本文中,我们将学习如何从一个J2ME客户机上向服务器发送一条HTTP GET请求和一条HTTP POST请
求。虽然这只是一篇探讨性质的文章,但是我还是假定读者已经熟悉Java,J2ME,以及Java Midlets(MIDP应
用程序)的运作机制。我们将使用J2ME的MIDP简表,并利用SUN的J2ME的无线应用程序开发工具包编译、配
置和测试我们的应用程序。对于HTTP服务器,任何WWW地址都可以被访问,但是默认时我们将使用一个简单
的Java Servlet来返回我们的HTTP请求的细节。
如何使用J2ME客户机向Web服务器和类似的支持HTTP的服务器发送HTTP请求呢?答案就是使用可在
javax.microedition.io程序包中可找到的J2ME的网络类。本文就想具体阐述这个问题。
本文概述∶
使用J2ME设计无线网络应用程序
.发送一条超文本GET请求
.发送一条超文本POST请求
.使用J2ME进行无线网络编程
Java的网络编程能力是相当健壮的。Java 2标准版( J2SE)在java.io和java.net程序包中定义了100多个接口
程序,类和异常。通过这些库实现的功能是很强大的,但是这只适用于传统的计算机系统,这些计算机系统有
强大的CPU处理能力,快速的内存和持久的数据储存,但是这些在大多数的无线设备上是不现实的。因此,
J2ME定义了这些函数的子集,并提供了一套用于网络和文件访问的固定的程序包--- javax.microedition.io程序
包。由于可移动设备种类繁多,这个程序包仅仅定义了一套接口,而为每个可移动设备供应厂商留下了实际的
应用程序接口实现。这就在可移植性和设备特定特征的应用中找到了一个最佳的平衡点。
定义在javax.microedition.io类中的抽象网络和文件输入输出框架称为通用连接框架(Generic Connection
Framework,简称GCF)。GCF定义了一套有关抽象化的内容来描述不同的通信方法。最高级的抽象被称作连
接(Connection),还声明了六个接口(四个是直接的,两个是间接的)。这七个接口就构成了J2ME的CLDC
的一部分,CLDC是大多数的能使用Java的无线设备使用的配置。设计这个配置的目的就是为所有的CLDC设备
(手提电话,双向传呼机,低档的PDA等等)提供公用的网络和文件输入输出能力。虽然GCF的目的是公用网络
和文件输入输出框架,但是生产商并不要求实现GCF中声明的所有的接口。有的厂家可以决定只支持socket连
接,而其它的厂家可以选择只支持基于数据报的通信。为了促进跨越类似装置的可移植性,MIDP规范要求所有
的MIDP设备实现HttpConnection接口。HttpConnection不是GCF的一部分,但是它是从GCF的一个接口
ContentConnection衍生出来的。我们将使用HttpConnection接口构造我们样本应用程序。
发送一个HTTP GET请求
这一节将重点解释程序代码,在下一节中我们将只讲述被用来发送HTTP请求并检索由服务器返回的响应通
用连接框架接口和HttpConnection接口。创建MIDP用户界面的程序代码见附录。
我们先要定义一个方法来放用于发送HTTP GET请求的代码。因为这个方法中的有些操作有潜在的抛出
IOException的可能,所以我们将把这样的意外(exception)抛给调用方法。
public String sendHttpGet( String url ) throws IOException { HttpConnection hcon = null; DataInputStream dis = null; StringBuffer message = ""; try {
|
第一步是使用Connector类打开一个到服务器的连接,这是GCF的关键。我们将把这个连接强制转换为需
第一步是使用Connector类打开一个到服务器的连接,这是GCF的关键。我们将把这个连接强制转换为需
要的类型,在本例中为HttpConnection类型。
hcon = ( HttpConnection ) Connector.open( url );
|
接下来,我们得到HttpConnection上的一个DataInputStream,允许我们一个字符一个字符的读取服务器
接下来,我们得到HttpConnection上的一个DataInputStream,允许我们一个字符一个字符的读取服务器
的响应数据。
dis = new DataInputStream( hcon.openInputStream() );
|
使用DataInputStream的read ()方法,服务器响应的每个字符都被集中起来放入StringBuffer对象。
int ch; while ( ( ch = dis.read() ) != -1 ) { message = message.append( ( char ) ch ); }
|
最后,连接对象被净空以保存资源,而信息从这个方法中返回。
} finally { if ( hcon != null ) hcon.close(); if ( dis != null ) dis.close(); }//结束try/finally代码段 return message.toString(); }//结束 sendGetRequest( String )
|
如何发送一个HTTP POST请求
你可以想象,发送一个HTTP POST请求的处理过程其实与发送一个GET请求非常地类似。我们将修改一个
现有命令,添加少量的新的命令,并添加一个来自通用连接框架的附加的对象和一个附加的StringBuffer对象把
POST请求体重的内容发送到服务器中。剩下的命令将保持不变。
复制我们刚才创建的sendHttpGet()方法,把它粘贴进同一个类文件,改名为sendHttpPost()。 现在,我
们将修改这个新方法来发送一个HTTP POST请求到服务器。 在方法的顶部添加两个新的变量说明。 声明一个
类型为DataOutputStream的变量和另一个String类型的变量。 我们将使用DataOutputStream对象把存在于字
符串变量中的POST请求体发送到服务器中。
DataOutputStream dos = null; String requestBody = null;
|
修改connector.open()命令包含另一个参数,指出连接将允许客户端可以通过连接在服务器上读和写。
hcon = ( HttpConnection ) Connector.open( url, Connector.READ_WRITE );
|
设置HttpConnection对象使用的请求方法为POST(默认的方法是GET)。
hcon.setRequestMethod( HttpConnection.POST );
|
得到一个用于现有的HTTP连接的DataOutputStream对象。
dos = hc.openDataOutputStream();
|
声明一个字节数组并通过检索一个来自requestBody字符串的字节数组初始化。 然后把DataOutputStream
声明一个字节数组并通过检索一个来自requestBody字符串的字节数组初始化。 然后把DataOutputStream
的缓冲写入字节数组内。
byte[] byteRequest = requestBody.getBytes(); for( int i = 0; i < byteRequest.length; i++ ) { dos.writeByte(byteRequest[i]); }//结束for( int i = 0; i < byteRequest.length; i++ )
dos.flush(); //包含本句,在某些设被上将可能会产生不可预期的结果
|
调用flush ()方法的意图是发送已经写入的数据到DataOutputStream的服务器的缓冲区中。 在某些电话
调用flush ()方法的意图是发送已经写入的数据到DataOutputStream的服务器的缓冲区中。 在某些电话
上,这个操作工作正常,在其他的电话上,它导致HTTP请求的Transfer - Encoding被设置为" chunked ",有一
些随机字符被放到请求本身的前面和后面。那又怎样处理这个问题呢?这个方法调用实际上是根本不需要的。
在接下来的一行中,服务器连接打开(通过openInputStream ()),将自动输入缓冲区。因此,你最好不要调
用缓冲区的flush()方法。这个方法其余的部分保持不变,除了DataOutputStream对象必须在finally{}语句块中关
闭。
} finally { if ( hc != null ) hc.close();
if ( dis != null ) dis.close();
if ( dos != null ) dis.close(); }//结束 try/finally
|
这就是所有的程序代码!并请参见本文后附带的程序代码。
随着可以使用国际互联网络和支持网络的无线设备日益的增多普及,Java和J2ME的重要性也在不断的变
这就是所有的程序代码!并请参见本文后附带的程序代码。
随着可以使用国际互联网络和支持网络的无线设备日益的增多普及,Java和J2ME的重要性也在不断的变
大。因为HTTP协议是当前仅有的,被所有的遵从MIDP规范的设备支持的网络协议,它也是用于开发无线网络
应用程序的最好的候选者。
在本文中,我们探究了无线网络编程的基本结构和几个核心问题,我们看了如何调用两个最常用的HTTP请
求方法:GET和POST。J2ME仍然在它的发展初期,并且无线设备也即将得到大面积的普及。所以,所有有志
投身于无线网络编程中的开发者们将得到大展拳脚的好机会。
附录:
/* * HttpMidlet.java */ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.io.*; import java.io.*;
public class HttpMidlet extends MIDlet implements CommandListener { //使用默认的URL。用户可以从图形用户接口改变这个值 private static String defaultURL = "http://localhost:8080/test/servlet/EchoServlet";
// 主MIDP 显示 private Display myDisplay = null;
// 输入URL的图形用户接口组件 private Form requestScreen; private TextField requestField;
// 用于提交请求的图形用户接口组件 private List list; private String[] menuItems;
// 用于显示服务器响应的图形用户接口组件 private Form resultScreen; private StringItem resultField;
//用于requestScreen的"send"按钮 Command sendCommand; // 用于requestScreen的"exit"按钮 Command exitCommand; // 用于requestScreen的"back"按钮 Command backCommand;
public HttpMidlet(){ // 初始化图形用户接口组件 myDisplay = Display.getDisplay( this ); sendCommand = new Command( "SEND", Command.OK, 1 ); exitCommand = new Command( "EXIT", Command.OK, 1 ); backCommand = new Command( "BACK", Command.OK, 1 );
//显示请求的URL requestScreen = new Form( "Type in a URL:" ); requestField = new TextField( null, defaultURL, 100, TextField.URL ); requestScreen.append( requestField ); requestScreen.addCommand( sendCommand ); requestScreen.addCommand( exitCommand ); requestScreen.setCommandListener( this );
// 选择想要的HTTP请求方法 menuItems = new String[] {"GET Request", "POST Request"}; list = new List( "Select an HTTP method:", List.IMPLICIT, menuItems, null ); list.setCommandListener( this );
// 先是从服务器上收到的信息 resultScreen = new Form( "Server Response:" ); resultScreen.addCommand( backCommand ); resultScreen.setCommandListener( this );
}//结束HttpMidlet()
public void startApp() { myDisplay.setCurrent( requestScreen ); }//结束 startApp()
public void commandAction( Command com, Displayable disp ) { // 当用户点击"send"按钮 if ( com == sendCommand ) { myDisplay.setCurrent( list ); } else if ( com == backCommand ) { requestField.setString( defaultURL ); myDisplay.setCurrent( requestScreen ); } else if ( com == exitCommand ) { destroyApp( true ); notifyDestroyed(); }//结束 if ( com == sendCommand )
if ( disp == list && com == List.SELECT_COMMAND ) {
String result;
if ( list.getSelectedIndex() == 0 ) // 发送一个 GET 请求到服务器 result = sendHttpGet( requestField.getString() ); else // 发送一个 POST 请求到服务器 result = sendHttpPost( requestField.getString() );
resultField = new StringItem( null, result ); resultScreen.append( resultField ); myDisplay.setCurrent( resultScreen ); }//结束if ( dis == list && com == List.SELECT_COMMAND ) }//结束 commandAction( Command, Displayable )
private String sendHttpGet( String url ) { HttpConnection hcon = null; DataInputStream dis = null; StringBuffer responseMessage = new StringBuffer();
try { //使用READ权限的标准的 HttpConnection hcon = ( HttpConnection )Connector.open( url );
//从HttpConnection取得一个 DataInputStream dis = new DataInputStream( hcon.openInputStream() );
// 从服务器上取回响应 int ch; while ( ( ch = dis.read() ) != -1 ) { responseMessage.append( (char) ch ); }//结束while ( ( ch = dis.read() ) != -1 ) } catch( Exception e ) { e.printStackTrace(); responseMessage.append( "ERROR" ); } finally { try { if ( hcon != null ) hcon.close(); if ( dis != null ) dis.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); }//结束try/catch }//结束try/catch/finally return responseMessage.toString(); }//结束sendHttpGet( String )
private String sendHttpPost( String url ) { HttpConnection hcon = null; DataInputStream dis = null; DataOutputStream dos = null; StringBuffer responseMessage = new StringBuffer(); // 请求体 String requeststring = "This is a POST.";
try { // 使用读写权限的 HttpConnection hcon = ( HttpConnection )Connector.open( url, Connector.READ_WRITE );
//设置请求方法为POST hcon.setRequestMethod( HttpConnection.POST );
// 取得发送请求字符串的DataOutputStream dos = hcon.openDataOutputStream(); byte[] request_body = requeststring.getBytes();
// 发送请求字符串到服务器 for( int i = 0; i < request_body.length; i++ ) { dos.writeByte( request_body[i] ); }//结束 for( int i = 0; i < request_body.length; i++ )
// 取得做为接收服务器响应的DataInputStream dis = new DataInputStream( hcon.openInputStream() );
// 从服务器上取回响应 int ch; while( ( ch = dis.read() ) != -1 ) { responseMessage.append( (char)ch ); }//结束while( ( ch = dis.read() ) != -1 ) { } catch( Exception e ) { e.printStackTrace(); responseMessage.append( "ERROR" ); } finally { // 释放输入输出流和HTTP连接 try { if( hcon != null ) hcon.close(); if( dis != null ) dis.close(); if( dos != null ) dos.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); }//结束try/catch }//结束try/catch/finally return responseMessage.toString(); }//结束sendHttpPost( String )
public void pauseApp() { }//结束pauseApp()
public void destroyApp( boolean unconditional ) { myDisplay = null; requestScreen = null; requestField = null; resultScreen = null; resultField = null; }//结束 destroyApp( boolean ) }//结束HttpMidlet
|
分享到:
相关推荐
在无线J2ME设备上实现HTTP传输涉及到的关键技术主要包括Java Micro Edition (J2ME)、MIDP(Mobile Information Device Profile)、HTTP协议以及J2ME的网络编程接口。J2ME是Java平台的一个轻量级版本,专为资源有限的...
在无线J2ME设备上实现超文本传输协议主要涉及到的是如何使用Java Micro Edition (J2ME)技术在有限资源的移动设备上与Web服务器进行通信。J2ME是一种轻量级的Java平台,专为嵌入式设备如手机、PDA等设计,它包括了...
4. **网络编程**:介绍MIDP的HttpConnection和UrlConnection类,以及如何在无线设备上实现HTTP通信,可能包括数据传输、文件上传下载等。 5. **设备适配**:讨论不同无线设备间的差异,如何进行设备检测和适配,以...
**J2ME无线设备编程** 是Java Micro Edition(Java ME)在无线设备上进行应用程序开发的重要领域。这一技术主要用于移动电话、智能手表、PDA等嵌入式设备,为这些设备提供丰富的应用程序和服务。 J2ME的核心是Java...
《J2ME MIDP无线设备编程指南》是针对在移动设备上进行软件开发的专业书籍,主要聚焦于Java Micro Edition(J2ME)平台中的Mobile Information Device Profile(MIDP),这是Java为移动和嵌入式设备设计的一个子集。...
特别是针对蓝牙无线技术的支持,J2ME提供了一个强大的框架——Java APIs for Bluetooth wireless technology (JABWT),这使得开发者能够轻松地在各种移动设备上开发蓝牙应用。 #### 二、Java蓝牙API概述 Java蓝牙...
《基于J2ME的无线设备编程源代码解析》是一份深入探讨J2ME(Java Micro Edition)技术在无线设备编程中的应用资源。J2ME是Java平台的一个子集,专门设计用于资源受限的移动设备,如手机、PDA和智能家电。这份资料...
6. **网络编程**:J2ME提供了HttpConnection和Socket连接,使开发者可以实现无线设备上的网络通信,包括HTTP请求、数据传输和TCP/IP连接。 7. **游戏开发**:J2ME的Canvas类允许创建自定义的绘图和动画,适合开发...
本方案通过集成GPRS无线通信模块,实现在嵌入式Linux系统中的无线数据传输。通过这种方式,用户可以利用内置的嵌入式浏览器ViewML浏览网页,并下载安装MIDlet程序。 ##### 3.4 文件下载与安装 为了方便用户获取并...
在IT行业中,尤其是在移动应用开发领域,针对不同的设备进行适配是至关重要的。本文将详细介绍三款索尼爱立信的手机设备定义,这些定义专...熟悉这些设备定义将使开发者能够在J2ME平台上构建高效且用户友好的移动应用。
在实现J2ME网络编程时,通常需要一个Web服务器来存储和处理数据,协调客户端的请求。Tomcat是一个广泛使用的开源Java Servlet容器,可以作为Web服务器来部署和运行Java应用程序。 搭建Tomcat的过程如下: 1. 首先...
4. **无线网络协议**:讲解如何利用J2ME接口实现蓝牙、Wi-Fi、GPRS等无线网络协议,包括连接建立、数据传输和错误处理。 5. **移动应用开发**:讨论如何设计和实现面向移动用户的交互界面,以及如何优化资源使用以...
在J2ME中,无线通信技术的应用开发是核心领域之一,它使得设备能够通过无线网络进行数据交换,实现各种丰富的功能和服务。 **1. J2ME架构与配置** J2ME由多个配置(Configurations)和Profile(Profiles)组成。...
J2ME是Java的一种轻量级版本,常用于移动设备,如早期的智能手机,它提供了在这些设备上开发应用程序的框架。 描述中提到的“bexDemo,不错的例子”,暗示我们有一个名为bexDemo的示例应用,该应用展示了如何利用...
《精通J2ME无线编程》是一本专注于Java Micro Edition(J2ME)技术在无线设备上应用的专业书籍。J2ME是Java平台的一个子集,主要用于嵌入式系统,如移动电话、数字电视和各种物联网设备。这本书面向的读者是对J2ME...
MIDP(Mobile Information Device Profile)是J2ME中的一个重要配置,它为开发无线设备上的应用程序提供了API。MIDP 2.0是MIDP的一个升级版本,增加了许多新功能和改进,以提高用户体验和开发者便利性。 **一、MIDP...
6. **网络编程**: J2ME支持HTTP和WAP协议,可以进行数据传输。学习如何使用HttpConnection和StreamConnection进行网络通信是J2ME开发的关键技能。 7. **数据存储**: J2ME提供了Record Management System (RMS) 来...
综上所述,【j2me 手机蓝牙聊天系统】是一个基于J2ME的多用户即时通讯应用,通过蓝牙技术实现在移动设备间的通信。它涉及到蓝牙协议、J2ME编程、服务器-客户端架构以及用户界面设计等多个技术领域,提供了一种在没有...