日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

J2ME編程實(shí)踐之聯(lián)網(wǎng)開發(fā)1_JSP教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:對(duì)SUN定義的四種JDBC驅(qū)動(dòng)程序標(biāo)準(zhǔn)簡介
SUN定義的四種JDBC驅(qū)動(dòng)程序標(biāo)準(zhǔn): Type1 JDBC-ODBC橋 作為JDK1.1后的一部分,是sun.jdbc.odbc包的一部分 ApplicationJDBC-ODBC Bridge(Type1 jdbc driver)-JDBC-ODBC LibraryODBC D

由于無線設(shè)備所能支持的網(wǎng)絡(luò)協(xié)議非常有限,僅限于HTTP,Socket,UDP等幾種協(xié)議,不同的廠家可能還支持其他網(wǎng)絡(luò)協(xié)議,但是,MIDP 1.0規(guī)范規(guī)定,HTTP協(xié)議是必須實(shí)現(xiàn)的協(xié)議,而其他協(xié)議的實(shí)現(xiàn)都是可選的。 因此,為了能在不同類型的手機(jī)上移植,我們盡量采用HTTP作為網(wǎng)絡(luò)連接的首選協(xié)議,這樣還能重用服務(wù)器端的代碼。但是,由于HTTP是一個(gè)基于文本的效率較低的協(xié)議,因此,必須仔細(xì)考慮手機(jī)和服務(wù)器端的通信內(nèi)容,盡可能地提高效率。

對(duì)于MIDP應(yīng)用程序,應(yīng)當(dāng)盡量做到:

1.發(fā)送請(qǐng)求時(shí),附加一個(gè)User-Agent頭,傳入MIDP和自身版本號(hào),以便服務(wù)器能識(shí)別此請(qǐng)求來自MIDP應(yīng)用程序,并且根據(jù)版本號(hào)發(fā)送相應(yīng)的相應(yīng)。

2.連接服務(wù)器時(shí),顯示一個(gè)下載進(jìn)度條使用戶能看到下載進(jìn)度,并能隨時(shí)中斷連接。

3.由于無線網(wǎng)絡(luò)連接速度還很慢,因此有必要將某些數(shù)據(jù)緩存起來,可以存儲(chǔ)在內(nèi)存中,也可以放到RMS中。

對(duì)于服務(wù)器端而言,其輸出響應(yīng)應(yīng)當(dāng)盡量做到:

1. 明確設(shè)置Content-Length字段,以便MIDP應(yīng)用程序能讀取HTTP頭并判斷自身是否有能力處理此長度的數(shù)據(jù),如果不能,可以直接關(guān)閉連接而不必繼續(xù)讀取HTTP正文。

2. 服務(wù)器不應(yīng)當(dāng)發(fā)送HTML內(nèi)容,因?yàn)镸IDP應(yīng)用程序很難解析HTML,XML雖然能夠解析,但是耗費(fèi)CPU和內(nèi)存資源,因此,應(yīng)當(dāng)發(fā)送緊湊的二進(jìn)制內(nèi)容,用DataOutputStream直接寫入并設(shè)置Content-Type為application/octet-stream。

3. 盡量不要重定向URL,這樣會(huì)導(dǎo)致MIDP應(yīng)用程序再次連接服務(wù)器,增加了用戶的等待時(shí)間和網(wǎng)絡(luò)流量。

4. 如果發(fā)生異常,例如請(qǐng)求的資源未找到,或者身份驗(yàn)證失敗,通常,服務(wù)器會(huì)向?yàn)g覽器發(fā)送一個(gè)顯示出錯(cuò)的頁面,可能還包括一個(gè)用戶登錄的Form,但是,向MIDP發(fā)送錯(cuò)誤頁面毫無意義,應(yīng)當(dāng)直接發(fā)送一個(gè)404或401錯(cuò)誤,這樣MIDP應(yīng)用程序就可以直接讀取HTTP頭的響應(yīng)碼獲取錯(cuò)誤信息而不必繼續(xù)讀取相應(yīng)內(nèi)容。

5. 由于服務(wù)器的計(jì)算能力遠(yuǎn)遠(yuǎn)超過手機(jī)客戶端,因此,針對(duì)不同客戶端版本發(fā)送不同響應(yīng)的任務(wù)應(yīng)該在服務(wù)器端完成。例如,根據(jù)客戶端傳送的User-Agent頭確定客戶端版本。這樣,低版本的客戶端不必升級(jí)也能繼續(xù)使用。

MIDP的聯(lián)網(wǎng)框架定義了多種協(xié)議的網(wǎng)絡(luò)連接,但是每個(gè)廠商都必須實(shí)現(xiàn)HTTP連接,在MIDP 2.0中還增加了必須實(shí)現(xiàn)的HTTPS連接。因此,要保證MIDP應(yīng)用程序能在不同廠商的手機(jī)平臺(tái)上移植,最好只使用HTTP連接。雖然HTTP是一個(gè)基于文本的效率較低的協(xié)議,但是由于使用特別廣泛,大多數(shù)服務(wù)器應(yīng)用的前端都是基于HTTP的Web頁面,因此能最大限度地復(fù)用服務(wù)器端的代碼。只要控制好緩存,仍然有不錯(cuò)的速度。

SUN的MIDP庫提供了javax.microediton.io包,能非常容易地實(shí)現(xiàn)HTTP連接。但是要注意,由于網(wǎng)絡(luò)有很大的延時(shí),必須把聯(lián)網(wǎng)操作放入一個(gè)單獨(dú)的線程中,以避免主線程阻塞導(dǎo)致用戶界面停止響應(yīng)。事實(shí)上,MIDP運(yùn)行環(huán)境根本就不允許在主線程中操作網(wǎng)絡(luò)連接。因此,我們必須實(shí)現(xiàn)一個(gè)靈活的HTTP聯(lián)網(wǎng)模塊,能讓用戶非常直觀地看到當(dāng)前上傳和下載的進(jìn)度,并且能夠隨時(shí)取消連接。

一個(gè)完整的HTTP連接為:用戶通過某個(gè)命令發(fā)起連接請(qǐng)求,然后系統(tǒng)給出一個(gè)等待屏幕提示正在連接,當(dāng)連接正常結(jié)束后,前進(jìn)到下一個(gè)屏幕并處理下載的數(shù)據(jù)。如果連接過程出現(xiàn)異常,將給用戶提示并返回到前一個(gè)屏幕。用戶在等待過程中能夠隨時(shí)取消并返回前一個(gè)屏幕。

我們?cè)O(shè)計(jì)一個(gè)HttpThread線程類負(fù)責(zé)在后臺(tái)連接服務(wù)器,HttpListener接口實(shí)現(xiàn)Observer(觀察者)模式,以便HttpThread能提示觀察者下載開始、下載結(jié)束、更新進(jìn)度條等。HttpListener接口如下:

public interface HttpListener {

void onSetSize(int size);

void onFinish(byte[] data, int size);

void onProgress(int percent);

void onError(int code, String message);

}

實(shí)現(xiàn)HttpListener接口的是繼承自Form的一個(gè)HttpWaitUI屏幕,它顯示一個(gè)進(jìn)度條和一些提示信息,并允許用戶隨時(shí)中斷連接:

public class HttpWaitUI extends Form implements CommandListener,

HttpListener {

private Gauge gauge;

private Command cancel;

private HttpThread downloader;

private Displayable displayable;

public HttpWaitUI(String url, Displayable displayable) {

super("Connecting");

this.gauge = new Gauge("Progress", false, 100, 0);

this.cancel = new Command("Cancel", Command.CANCEL, 0);

append(gauge);

addCommand(cancel);

setCommandListener(this);

downloader = new HttpThread(url, this);

downloader.start();

}

public void commandAction(Command c, Displayable d) {

if(c==cancel) {

downloader.cancel();

ControllerMIDlet.goBack();

}

}

public void onFinish(byte[] buffer, int size) { … }

public void onError(int code, String message) { … }

public void onProgress(int percent) { … }

public void onSetSize(int size) { … }

}

HttpThread是負(fù)責(zé)處理Http連接的線程類,它接受一個(gè)URL和HttpListener:

class HttpThread extends Thread {

private static final int MAX_LENGTH = 20 * 1024; // 20K

private boolean cancel = false;

private String url;

private byte[] buffer = null;

private HttpListener listener;

public HttpThread(String url, HttpListener listener) {

this.url = url;

this.listener = listener;

}

public void cancel() { cancel = true; }

使用GET獲取內(nèi)容

我們先討論最簡單的GET請(qǐng)求。GET請(qǐng)求只需向服務(wù)器發(fā)送一個(gè)URL,然后取得服務(wù)器響應(yīng)即可。在HttpThread的run()方法中實(shí)現(xiàn)如下:

public void run() {

HttpConnection hc = null;

InputStream input = null;

try {

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

hc.setRequestMethod(HttpConnection.GET); // 默認(rèn)即為GET

hc.setRequestProperty("User-Agent", USER_AGENT);

// get response code:

int code = hc.getResponseCode();

if(code!=HttpConnection.HTTP_OK) {

listener.onError(code, hc.getResponseMessage());

return;

}

// get size:

int size = (int)hc.getLength();

// 返回響應(yīng)大小,或者-1如果大小無法確定

listener.onSetSize(size);

// 開始讀響應(yīng):

input = hc.openInputStream();

int percent = 0; // percentage

int tmp_percent = 0;

int index = 0; // buffer index

int reads; // each byte

if(size!=(-1))

buffer = new byte[size]; // 響應(yīng)大小已知,確定緩沖區(qū)大小

else

buffer = new byte[MAX_LENGTH];

// 響應(yīng)大小未知,設(shè)定一個(gè)固定大小的緩沖區(qū)

while(!cancel) {

int len = buffer.length - index;

len = len>128 ? 128 : len;

reads = input.read(buffer, index, len);

if(reads<=0)

break;

index = reads;

if(size>0) { // 更新進(jìn)度

tmp_percent = index * 100 / size;

if(tmp_percent!=percent) {

percent = tmp_percent;

listener.onProgress(percent);

}

}

}

if(!cancel && input.available()>0) // 緩沖區(qū)已滿,無法繼續(xù)讀取

listener.onError(601, "Buffer overflow.");

if(!cancel) {

if(size!=(-1) && index!=size)

listener.onError(102, "Content-Length does not match.");

else

listener.onFinish(buffer, index);

}

}

catch(IOException ioe) {

listener.onError(101, "IOException: " ioe.getMessage());

}

finally { // 清理資源

if(input!=null)

try { input.close(); } catch(IOException ioe) {}

if(hc!=null)

try { hc.close(); } catch(IOException ioe) {}

}

}

當(dāng)下載完畢后,HttpWaitUI就獲得了來自服務(wù)器的數(shù)據(jù),要傳遞給下一個(gè)屏幕處理,HttpWaitUI必須包含對(duì)此屏幕的引用并通過一個(gè)setData(DataInputStream input)方法讓下一個(gè)屏幕能非常方便地讀取數(shù)據(jù)。因此,定義一個(gè)DataHandler接口:

public interface DataHandler {

void setData(DataInputStream input) throws IOException;

}

HttpWaitUI響應(yīng)HttpThread的onFinish事件并調(diào)用下一個(gè)屏幕的setData方法將數(shù)據(jù)傳遞給它并顯示下一個(gè)屏幕:

public void onFinish(byte[] buffer, int size) {

byte[] data = buffer;

if(size!=buffer.length) {

data = new byte[size];

System.arraycopy(data, 0, buffer, 0, size);

}

DataInputStream input = null;

try {

input = new DataInputStream(new ByteArrayInputStream(data));

if(displayable instanceof DataHandler)

((DataHandler)displayable).setData(input);

else

System.err.println("[WARNING]

Displayable object cannot handle data.");

ControllerMIDlet.replace(displayable);

}

catch(IOException ioe) { … }

}

由于無線設(shè)備所能支持的網(wǎng)絡(luò)協(xié)議非常有限,僅限于HTTP,Socket,UDP等幾種協(xié)議,不同的廠家可能還支持其他網(wǎng)絡(luò)協(xié)議,但是,MIDP 1.0規(guī)范規(guī)定,HTTP協(xié)議是必須實(shí)現(xiàn)的協(xié)議,而其他協(xié)議的實(shí)現(xiàn)都是可選的。 因此,為了能在不同類型的手機(jī)上移植,我們盡量采用HTTP作為網(wǎng)絡(luò)連接的首選協(xié)議,這樣還能重用服務(wù)器端的代碼。但是,由于HTTP是一個(gè)基于文本的效率較低的協(xié)議,因此,必須仔細(xì)考慮手機(jī)和服務(wù)器端的通信內(nèi)容,盡可能地提高效率。

對(duì)于MIDP應(yīng)用程序,應(yīng)當(dāng)盡量做到:

1.發(fā)送請(qǐng)求時(shí),附加一個(gè)User-Agent頭,傳入MIDP和自身版本號(hào),以便服務(wù)器能識(shí)別此請(qǐng)求來自MIDP應(yīng)用程序,并且根據(jù)版本號(hào)發(fā)送相應(yīng)的相應(yīng)。

2.連接服務(wù)器時(shí),顯示一個(gè)下載進(jìn)度條使用戶能看到下載進(jìn)度,并能隨時(shí)中斷連接。

3.由于無線網(wǎng)絡(luò)連接速度還很慢,因此有必要將某些數(shù)據(jù)緩存起來,可以存儲(chǔ)在內(nèi)存中,也可以放到RMS中。

對(duì)于服務(wù)器端而言,其輸出響應(yīng)應(yīng)當(dāng)盡量做到:

1. 明確設(shè)置Content-Length字段,以便MIDP應(yīng)用程序能讀取HTTP頭并判斷自身是否有能力處理此長度的數(shù)據(jù),如果不能,可以直接關(guān)閉連接而不必繼續(xù)讀取HTTP正文。

2. 服務(wù)器不應(yīng)當(dāng)發(fā)送HTML內(nèi)容,因?yàn)镸IDP應(yīng)用程序很難解析HTML,XML雖然能夠解析,但是耗費(fèi)CPU和內(nèi)存資源,因此,應(yīng)當(dāng)發(fā)送緊湊的二進(jìn)制內(nèi)容,用DataOutputStream直接寫入并設(shè)置Content-Type為application/octet-stream。

3. 盡量不要重定向URL,這樣會(huì)導(dǎo)致MIDP應(yīng)用程序再次連接服務(wù)器,增加了用戶的等待時(shí)間和網(wǎng)絡(luò)流量。

4. 如果發(fā)生異常,例如請(qǐng)求的資源未找到,或者身份驗(yàn)證失敗,通常,服務(wù)器會(huì)向?yàn)g覽器發(fā)送一個(gè)顯示出錯(cuò)的頁面,可能還包括一個(gè)用戶登錄的Form,但是,向MIDP發(fā)送錯(cuò)誤頁面毫無意義,應(yīng)當(dāng)直接發(fā)送一個(gè)404或401錯(cuò)誤,這樣MIDP應(yīng)用程序就可以直接讀取HTTP頭的響應(yīng)碼獲取錯(cuò)誤信息而不必繼續(xù)讀取相應(yīng)內(nèi)容。

5. 由于服務(wù)器的計(jì)算能力遠(yuǎn)遠(yuǎn)超過手機(jī)客戶端,因此,針對(duì)不同客戶端版本發(fā)送不同響應(yīng)的任務(wù)應(yīng)該在服務(wù)器端完成。例如,根據(jù)客戶端傳送的User-Agent頭確定客戶端版本。這樣,低版本的客戶端不必升級(jí)也能繼續(xù)使用。

MIDP的聯(lián)網(wǎng)框架定義了多種協(xié)議的網(wǎng)絡(luò)連接,但是每個(gè)廠商都必須實(shí)現(xiàn)HTTP連接,在MIDP 2.0中還增加了必須實(shí)現(xiàn)的HTTPS連接。因此,要保證MIDP應(yīng)用程序能在不同廠商的手機(jī)平臺(tái)上移植,最好只使用HTTP連接。雖然HTTP是一個(gè)基于文本的效率較低的協(xié)議,但是由于使用特別廣泛,大多數(shù)服務(wù)器應(yīng)用的前端都是基于HTTP的Web頁面,因此能最大限度地復(fù)用服務(wù)器端的代碼。只要控制好緩存,仍然有不錯(cuò)的速度。

SUN的MIDP庫提供了javax.microediton.io包,能非常容易地實(shí)現(xiàn)HTTP連接。但是要注意,由于網(wǎng)絡(luò)有很大的延時(shí),必須把聯(lián)網(wǎng)操作放入一個(gè)單獨(dú)的線程中,以避免主線程阻塞導(dǎo)致用戶界面停止響應(yīng)。事實(shí)上,MIDP運(yùn)行環(huán)境根本就不允許在主線程中操作網(wǎng)絡(luò)連接。因此,我們必須實(shí)現(xiàn)一個(gè)靈活的HTTP聯(lián)網(wǎng)模塊,能讓用戶非常直觀地看到當(dāng)前上傳和下載的進(jìn)度,并且能夠隨時(shí)取消連接。

一個(gè)完整的HTTP連接為:用戶通過某個(gè)命令發(fā)起連接請(qǐng)求,然后系統(tǒng)給出一個(gè)等待屏幕提示正在連接,當(dāng)連接正常結(jié)束后,前進(jìn)到下一個(gè)屏幕并處理下載的數(shù)據(jù)。如果連接過程出現(xiàn)異常,將給用戶提示并返回到前一個(gè)屏幕。用戶在等待過程中能夠隨時(shí)取消并返回前一個(gè)屏幕。

我們?cè)O(shè)計(jì)一個(gè)HttpThread線程類負(fù)責(zé)在后臺(tái)連接服務(wù)器,HttpListener接口實(shí)現(xiàn)Observer(觀察者)模式,以便HttpThread能提示觀察者下載開始、下載結(jié)束、更新進(jìn)度條等。HttpListener接口如下:

public interface HttpListener {

void onSetSize(int size);

void onFinish(byte[] data, int size);

void onProgress(int percent);

void onError(int code, String message);

}

實(shí)現(xiàn)HttpListener接口的是繼承自Form的一個(gè)HttpWaitUI屏幕,它顯示一個(gè)進(jìn)度條和一些提示信息,并允許用戶隨時(shí)中斷連接:

public class HttpWaitUI extends Form implements CommandListener,

HttpListener {

private Gauge gauge;

private Command cancel;

private HttpThread downloader;

private Displayable displayable;

public HttpWaitUI(String url, Displayable displayable) {

super("Connecting");

this.gauge = new Gauge("Progress", false, 100, 0);

this.cancel = new Command("Cancel", Command.CANCEL, 0);

append(gauge);

addCommand(cancel);

setCommandListener(this);

downloader = new HttpThread(url, this);

downloader.start();

}

public void commandAction(Command c, Displayable d) {

if(c==cancel) {

downloader.cancel();

ControllerMIDlet.goBack();

}

}

public void onFinish(byte[] buffer, int size) { … }

public void onError(int code, String message) { … }

public void onProgress(int percent) { … }

public void onSetSize(int size) { … }

}

HttpThread是負(fù)責(zé)處理Http連接的線程類,它接受一個(gè)URL和HttpListener:

class HttpThread extends Thread {

private static final int MAX_LENGTH = 20 * 1024; // 20K

private boolean cancel = false;

private String url;

private byte[] buffer = null;

private HttpListener listener;

public HttpThread(String url, HttpListener listener) {

this.url = url;

this.listener = listener;

}

public void cancel() { cancel = true; }

使用GET獲取內(nèi)容

我們先討論最簡單的GET請(qǐng)求。GET請(qǐng)求只需向服務(wù)器發(fā)送一個(gè)URL,然后取得服務(wù)器響應(yīng)即可。在HttpThread的run()方法中實(shí)現(xiàn)如下:

public void run() {

HttpConnection hc = null;

InputStream input = null;

try {

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

hc.setRequestMethod(HttpConnection.GET); // 默認(rèn)即為GET

hc.setRequestProperty("User-Agent", USER_AGENT);

// get response code:

int code = hc.getResponseCode();

if(code!=HttpConnection.HTTP_OK) {

listener.onError(code, hc.getResponseMessage());

return;

}

// get size:

int size = (int)hc.getLength();

// 返回響應(yīng)大小,或者-1如果大小無法確定

listener.onSetSize(size);

// 開始讀響應(yīng):

input = hc.openInputStream();

int percent = 0; // percentage

int tmp_percent = 0;

int index = 0; // buffer index

int reads; // each byte

if(size!=(-1))

buffer = new byte[size]; // 響應(yīng)大小已知,確定緩沖區(qū)大小

else

buffer = new byte[MAX_LENGTH];

// 響應(yīng)大小未知,設(shè)定一個(gè)固定大小的緩沖區(qū)

while(!cancel) {

int len = buffer.length - index;

len = len>128 ? 128 : len;

reads = input.read(buffer, index, len);

if(reads<=0)

break;

index = reads;

if(size>0) { // 更新進(jìn)度

tmp_percent = index * 100 / size;

if(tmp_percent!=percent) {

percent = tmp_percent;

listener.onProgress(percent);

}

}

}

if(!cancel && input.available()>0) // 緩沖區(qū)已滿,無法繼續(xù)讀取

listener.onError(601, "Buffer overflow.");

if(!cancel) {

if(size!=(-1) && index!=size)

listener.onError(102, "Content-Length does not match.");

else

listener.onFinish(buffer, index);

}

}

catch(IOException ioe) {

listener.onError(101, "IOException: " ioe.getMessage());

}

finally { // 清理資源

if(input!=null)

try { input.close(); } catch(IOException ioe) {}

if(hc!=null)

try { hc.close(); } catch(IOException ioe) {}

}

}

當(dāng)下載完畢后,HttpWaitUI就獲得了來自服務(wù)器的數(shù)據(jù),要傳遞給下一個(gè)屏幕處理,HttpWaitUI必須包含對(duì)此屏幕的引用并通過一個(gè)setData(DataInputStream input)方法讓下一個(gè)屏幕能非常方便地讀取數(shù)據(jù)。因此,定義一個(gè)DataHandler接口:

public interface DataHandler {

void setData(DataInputStream input) throws IOException;

}

HttpWaitUI響應(yīng)HttpThread的onFinish事件并調(diào)用下一個(gè)屏幕的setData方法將數(shù)據(jù)傳遞給它并顯示下一個(gè)屏幕:

public void onFinish(byte[] buffer, int size) {

byte[] data = buffer;

if(size!=buffer.length) {

data = new byte[size];

System.arraycopy(data, 0, buffer, 0, size);

}

DataInputStream input = null;

try {

input = new DataInputStream(new ByteArrayInputStream(data));

if(displayable instanceof DataHandler)

((DataHandler)displayable).setData(input);

else

System.err.println("[WARNING]

Displayable object cannot handle data.");

ControllerMIDlet.replace(displayable);

}

catch(IOException ioe) { … }

}

  

分享:JSP頁面自動(dòng)生成html頁面或任何格式頁面
先建立一個(gè)模本頁面:template.htm ###title### ###title### 作者:###author### ###content###=========================================再寫一個(gè)JSP頁面: buildhtml.jsp

來源:模板無憂//所屬分類:JSP教程/更新時(shí)間:2008-08-22
相關(guān)JSP教程