溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在無線J2ME設(shè)備上實現(xiàn)超文本傳輸協(xié)議

發(fā)布時間:2021-11-20 16:56:28 來源:億速云 閱讀:128 作者:小新 欄目:編程語言

這篇文章主要介紹如何在無線J2ME設(shè)備上實現(xiàn)超文本傳輸協(xié)議,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

隨著越來越多手提電話和個人數(shù)字助理開始融入到信息高速公路之上,從移動設(shè)備上訪問web站點變得越來越重要。Java開創(chuàng)了消費設(shè)備中小型的儲存容量的先河,它是用于開發(fā)手機、傳呼機及其他微型設(shè)備應(yīng)用程序的理想語言。

  在本文中,我們將學(xué)習(xí)如何從一個j2me客戶機上向服務(wù)器發(fā)送一條HTTP GET請求和一條HTTP POST請求。雖然這只是一篇探討性質(zhì)的文章,但是我還是假定讀者已經(jīng)熟悉Java,J2ME,以及Java Midlets(MIDP應(yīng)用程序)的運作機制。我們將使用J2ME的MIDP簡表,并利用SUN的J2ME的無線應(yīng)用程序開發(fā)工具包編譯、配置和測試我們的應(yīng)用程序。對于HTTP服務(wù)器,任何WWW地址都可以被訪問,但是默認時我們將使用一個簡單的Java servlet來返回我們的HTTP請求的細節(jié)。

  如何使用J2ME客戶機向Web服務(wù)器和類似的支持HTTP的服務(wù)器發(fā)送HTTP請求呢?答案就是使用可在javax.microedition.io程序包中可找到的J2ME的網(wǎng)絡(luò)類。本文就想具體闡述這個問題。

  本文概述∶

  使用J2ME設(shè)計無線網(wǎng)絡(luò)應(yīng)用程序

  .發(fā)送一條超文本GET請求

  .發(fā)送一條超文本POST請求

  .使用J2ME進行無線網(wǎng)絡(luò)編程

  Java的網(wǎng)絡(luò)編程能力是相當健壯的。Java 2標準版( j2se)在java.io和java.NET程序包中定義了100多個接口程序,類和異常。通過這些庫實現(xiàn)的功能是很強大的,但是這只適用于傳統(tǒng)的計算機系統(tǒng),這些計算機系統(tǒng)有強大的cpu處理能力,快速的內(nèi)存和持久的數(shù)據(jù)儲存,但是這些在大多數(shù)的無線設(shè)備上是不現(xiàn)實的。因此,J2ME定義了這些函數(shù)的子集,并提供了一套用于網(wǎng)絡(luò)和文件訪問的固定的程序包--- javax.microedition.io程序包。由于可移動設(shè)備種類繁多,這個程序包僅僅定義了一套接口,而為每個可移動設(shè)備供應(yīng)廠商留下了實際的應(yīng)用程序接口實現(xiàn)。這就在可移植性和設(shè)備特定特征的應(yīng)用中找到了一個最佳的平衡點。

  定義在javax.microedition.io類中的抽象網(wǎng)絡(luò)和文件輸入輸出框架稱為通用連接框架(Generic Connection framework,簡稱GCF)。GCF定義了一套有關(guān)抽象化的內(nèi)容來描述不同的通信方法。最高級的抽象被稱作連接(Connection),還聲明了六個接口(四個是直接的,兩個是間接的)。這七個接口就構(gòu)成了J2ME的CLDC的一部分,CLDC是大多數(shù)的能使用Java的無線設(shè)備使用的配置。設(shè)計這個配置的目的就是為所有的CLDC設(shè)備(手提電話,雙向傳呼機,低檔的PDA等等)提供公用的網(wǎng)絡(luò)和文件輸入輸出能力。雖然GCF的目的是公用網(wǎng)絡(luò)和文件輸入輸出框架,但是生產(chǎn)商并不要求實現(xiàn)GCF中聲明的所有的接口。有的廠家可以決定只支持socket連接,而其它的廠家可以選擇只支持基于數(shù)據(jù)報的通信。為了促進跨越類似裝置的可移植性,MIDP規(guī)范要求所有的MIDP設(shè)備實現(xiàn)HttpConnection接口。HttpConnection不是GCF的一部分,但是它是從GCF的一個接口ContentConnection衍生出來的。我們將使用HttpConnection接口構(gòu)造我們樣本應(yīng)用程序。

  發(fā)送一個HTTP GET請求

  這一節(jié)將重點解釋程序代碼,在下一節(jié)中我們將只講述被用來發(fā)送HTTP請求并檢索由服務(wù)器返回的響應(yīng)通用連接框架接口和HttpConnection接口。創(chuàng)建MIDP用戶界面的程序代碼見附錄。

  我們先要定義一個方法來放用于發(fā)送HTTP GET請求的代碼。因為這個方法中的有些操作有潛在的拋出IOException的可能,所以我們將把這樣的意外(exception)拋給調(diào)用方法。

public String sendHttpGet( String url ) throws IOException {
HttpConnection hcon = null;
DataInputStream dis = null;
StringBuffer message = "";
try {

  第一步是使用Connector類打開一個到服務(wù)器的連接,這是GCF的關(guān)鍵。我們將把這個連接強制轉(zhuǎn)換為需要的類型,在本例中為HttpConnection類型。

hcon = ( HttpConnection ) Connector.open( url );

  接下來,我們得到HttpConnection上的一個DataInputStream,允許我們一個字符一個字符的讀取服務(wù)器的響應(yīng)數(shù)據(jù)。

dis = new DataInputStream( hcon.openInputStream() );
  使用DataInputStream的read ()方法,服務(wù)器響應(yīng)的每個字符都被集中起來放入StringBuffer對象。

int ch;
while ( ( ch = dis.read() ) != -1 ) {
message = message.append( ( char ) ch );
}

  最后,連接對象被凈空以保存資源,而信息從這個方法中返回。

} finally {
if ( hcon != null ) hcon.close();
if ( dis != null ) dis.close();
}//結(jié)束try/finally代碼段
return message.toString();
}//結(jié)束 sendGetRequest( String )
  如何發(fā)送一個HTTP POST請求

  你可以想象,發(fā)送一個HTTP POST請求的處理過程其實與發(fā)送一個GET請求非常地類似。我們將修改一個現(xiàn)有命令,添加少量的新的命令,并添加一個來自通用連接框架的附加的對象和一個附加的StringBuffer對象把POST請求體重的內(nèi)容發(fā)送到服務(wù)器中。剩下的命令將保持不變。

  復(fù)制我們剛才創(chuàng)建的sendHttpGet()方法,把它粘貼進同一個類文件,改名為sendHttpPost()。 現(xiàn)在,我們將修改這個新方法來發(fā)送一個HTTP POST請求到服務(wù)器。 在方法的頂部添加兩個新的變量說明。 聲明一個類型為DataOutputStream的變量和另一個String類型的變量。 我們將使用DataOutputStream對象把存在于字符串變量中的POST請求體發(fā)送到服務(wù)器中。

DataOutputStream dos = null;
String requestBody = null;
  修改connector.open()命令包含另一個參數(shù),指出連接將允許客戶端可以通過連接在服務(wù)器上讀和寫。

hcon = ( HttpConnection ) Connector.open( url, Connector.READ_WRITE );
  設(shè)置HttpConnection對象使用的請求方法為POST(默認的方法是GET)。

hcon.setRequestMethod( HttpConnection.POST );
  得到一個用于現(xiàn)有的HTTP連接的DataOutputStream對象。

dos = hc.openDataOutputStream();
  聲明一個字節(jié)數(shù)組并通過檢索一個來自requestBody字符串的字節(jié)數(shù)組初始化。 然后把DataOutputStream的緩沖寫入字節(jié)數(shù)組內(nèi)。

byte[] byteRequest = requestBody.getBytes();
for( int i = 0; i < byteRequest.length; i++ ) {
dos.writeByte(byteRequest[i]);
}//結(jié)束for( int i = 0; i < byteRequest.length; i++ )

dos.flush(); //包含本句,在某些設(shè)被上將可能會產(chǎn)生不可預(yù)期的結(jié)果
  調(diào)用flush ()方法的意圖是發(fā)送已經(jīng)寫入的數(shù)據(jù)到DataOutputStream的服務(wù)器的緩沖區(qū)中。 在某些電話上,這個操作工作正常,在其他的電話上,它導(dǎo)致HTTP請求的Transfer - Encoding被設(shè)置為" chunked ",有一些隨機字符被放到請求本身的前面和后面。那又怎樣處理這個問題呢?這個方法調(diào)用實際上是根本不需要的。在接下來的一行中,服務(wù)器連接打開(通過openInputStream ()),將自動輸入緩沖區(qū)。因此,你最好不要調(diào)用緩沖區(qū)的flush()方法。這個方法其余的部分保持不變,除了DataOutputStream對象必須在finally{}語句塊中關(guān)閉。

} finally {
if ( hc != null ) hc.close();

if ( dis != null ) dis.close();

if ( dos != null ) dis.close();
}//結(jié)束 try/finally

  這就是所有的程序代碼!并請參見本文后附帶的程序代碼。

  隨著可以使用國際互聯(lián)網(wǎng)絡(luò)和支持網(wǎng)絡(luò)的無線設(shè)備日益的增多普及,Java和J2ME的重要性也在不斷的變大。因為http協(xié)議是當前僅有的,被所有的遵從MIDP規(guī)范的設(shè)備支持的網(wǎng)絡(luò)協(xié)議,它也是用于開發(fā)無線網(wǎng)絡(luò)應(yīng)用程序的最好的候選者。

  在本文中,我們探究了無線網(wǎng)絡(luò)編程的基本結(jié)構(gòu)和幾個核心問題,我們看了如何調(diào)用兩個最常用的HTTP請求方法:GET和POST。J2ME仍然在它的發(fā)展初期,并且無線設(shè)備也即將得到大面積的普及。所以,所有有志投身于無線網(wǎng)絡(luò)編程中的開發(fā)者們將得到大展拳腳的好機會。

  附錄:

/*
* 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;

// 用于顯示服務(wù)器響應(yīng)的圖形用戶接口組件
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 );

// 先是從服務(wù)器上收到的信息
resultScreen = new Form( "Server Response:" );
resultScreen.addCommand( backCommand );
resultScreen.setCommandListener( this );

}//結(jié)束HttpMidlet()

public void startApp() {
myDisplay.setCurrent( requestScreen );
}//結(jié)束 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();
}//結(jié)束 if ( com == sendCommand )

if ( disp == list && com == List.SELECT_COMMAND ) {

String result;

if ( list.getSelectedIndex() == 0 ) // 發(fā)送一個 GET 請求到服務(wù)器
result = sendHttpGet( requestField.getString() );
else // 發(fā)送一個 POST 請求到服務(wù)器
result = sendHttpPost( requestField.getString() );

resultField = new StringItem( null, result );
resultScreen.append( resultField );
myDisplay.setCurrent( resultScreen );
}//結(jié)束if ( dis == list && com == List.SELECT_COMMAND )
}//結(jié)束 commandAction( Command, Displayable )

private String sendHttpGet( String url )
{
HttpConnection hcon = null;
DataInputStream dis = null;
StringBuffer responseMessage = new StringBuffer();

try {
//使用READ權(quán)限的標準的 HttpConnection
hcon = ( HttpConnection )Connector.open( url );

//從HttpConnection取得一個 DataInputStream
dis = new DataInputStream( hcon.openInputStream() );

// 從服務(wù)器上取回響應(yīng)
int ch;
while ( ( ch = dis.read() ) != -1 ) {
responseMessage.append( (char) ch );
}//結(jié)束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();
}//結(jié)束try/catch
}//結(jié)束try/catch/finally
return responseMessage.toString();
}//結(jié)束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 {
// 使用讀寫權(quán)限的 HttpConnection
hcon = ( HttpConnection )Connector.open( url, Connector.READ_WRITE );

//設(shè)置請求方法為POST
hcon.setRequestMethod( HttpConnection.POST );

// 取得發(fā)送請求字符串的DataOutputStream
dos = hcon.openDataOutputStream();
byte[] request_body = requeststring.getBytes();

// 發(fā)送請求字符串到服務(wù)器
for( int i = 0; i < request_body.length; i++ ) {
dos.writeByte( request_body[i] );
}//結(jié)束 for( int i = 0; i < request_body.length; i++ )

// 取得做為接收服務(wù)器響應(yīng)的DataInputStream
dis = new DataInputStream( hcon.openInputStream() );

// 從服務(wù)器上取回響應(yīng)
int ch;
while( ( ch = dis.read() ) != -1 ) {
responseMessage.append( (char)ch );
}//結(jié)束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();
}//結(jié)束try/catch
}//結(jié)束try/catch/finally
return responseMessage.toString();
}//結(jié)束sendHttpPost( String )

public void pauseApp() {
}//結(jié)束pauseApp()

public void destroyApp( boolean unconditional ) {
myDisplay = null;
requestScreen = null;
requestField = null;
resultScreen = null;
resultField = null;
}//結(jié)束 destroyApp( boolean )
}//結(jié)束HttpMidlet

以上是“如何在無線J2ME設(shè)備上實現(xiàn)超文本傳輸協(xié)議”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI