首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 網路程式設計深度解析:Generic Connection Framework 與 HTTP 實戰

     編輯:J2ME

Generic Connection Framework (GCF) 架構

J2ME 網路存取核心為 javax.microedition.io 套件定義的 **Generic Connection Framework (GCF)**,採用工廠模式統一建立連線:


Connection conn = Connector.open("https://example.com/api");

協定由 URL Scheme 決定:http:, https:, socket:, datagram:, ssl:, comm: 等。

核心介面層次


Connection (介面)
  ├─ StreamConnection          // 雙向串流 (InputStream + OutputStream)
  │    ├─ ContentConnection    // 含長度/型別/編碼資訊 (getLength, getType, getEncoding)
  │    └─ HttpConnection       // HTTP 專用 (GET/POST/HEAD, 標頭操作, 狀態碼)
  ├─ DatagramConnection        // UDP 資料包
  └─ ... (其他)
  • CLDC 1.0 強制實作:StreamConnection, DatagramConnection
  • MIDP 強制實作:HttpConnection (含 ContentConnection)

HttpConnection 完整操作指南

1. 基本 GET 請求


HttpConnection conn = null;
InputStream is = null;
try {
    conn = (HttpConnection) Connector.open("https://example.com/data.txt");
    conn.setRequestMethod(HttpConnection.GET);
    
    int rc = conn.getResponseCode();
    if (rc == HttpConnection.HTTP_OK) {
        is = conn.openInputStream();
        // 讀取資料...
    } else {
        // 處理錯誤碼
    }
} finally {
    if (is != null) try { is.close(); } catch (Exception ignore) {}
    if (conn != null) try { conn.close(); } catch (Exception ignore) {}
}

2. POST 送出表單/JSON 資料


HttpConnection conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("Content-Length", String.valueOf(body.length()));

OutputStream os = conn.openOutputStream();
os.write(body.getBytes("UTF-8"));
os.flush();

// 讀取回應...

3. 利用 ContentConnection 取得內容長度 (配置緩衝區)


ContentConnection cconn = (ContentConnection) Connector.open(url);
long len = cconn.getLength(); // -1 表示未知 (Chunked 或動態生成)
if (len > 0 && len < MAX_BUFFER) {
    byte[] buf = new byte[(int) len];
    DataInputStream dis = cconn.openDataInputStream();
    dis.readFully(buf);
    // 處理完整資料
}

4. 標頭操作


// 請求標頭
conn.setRequestProperty("User-Agent", "MyMIDlet/1.0");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Cookie", cookieManager.getCookieHeader(url));

// 回應標頭
String contentType = conn.getHeaderField("Content-Type");
String setCookie = conn.getHeaderField("Set-Cookie");
Date expires = new Date(conn.getHeaderFieldDate("Expires", 0));

實戰案例:增強 Address Book MIDlet 從網路載入資料

原始設計:本地 RMS 儲存

先前範例使用 dbAddress.addAddress() 手動填入測試資料。

改造:使用 StreamConnection 從伺服器下載


// AddressDB 建構子中
StreamConnection conn = null;
InputStream in = null;
try {
    conn = (StreamConnection) Connector.open("https://server/addressbook.txt");
    in = conn.openInputStream();
    
    byte[] buf = new byte[256]; // StreamConnection 無 getLength,需固定緩衝區
    int count = in.read(buf);
    String content = new String(buf, 0, count).trim();
    
    // 解析:每行 "姓名,電話"
    StringTokenizer st = new StringTokenizer(content, "\n");
    while (st.hasMoreTokens()) {
        String line = st.nextToken();
        int comma = line.indexOf(',');
        if (comma > 0) {
            String name = line.substring(0, comma);
            String phone = line.substring(comma + 1);
            addAddress(name, phone); // 原有 RMS 寫入方法
        }
    }
} catch (IOException e) {
    // 錯誤處理...
} finally {
    // 關閉資源...
}

改良:使用 ContentConnection 精確配置緩衝區


ContentConnection cconn = (ContentConnection) Connector.open(url);
long len = cconn.getLength();
if (len > 0) {
    byte[] buf = new byte[(int) len];
    DataInputStream dis = cconn.openDataInputStream();
    dis.readFully(buf);
    // 解析...
}

注意:J2ME 缺少 java.util.StringTokenizer,需自行實作或使用第三方實作 (如 kxml 附屬工具類)。

網路程式設計最佳實踐

常見問題排除

  • ConnectionNotFoundException:檢查 URL 拼寫、裝置網路連線、MIDlet 權限 (MIDlet-Permissions: javax.microedition.io.Connector.http)
  • 回應截斷:getLength() 回傳 -1 時不可分配固定大小緩衝區,改用動態 ByteArrayOutputStream 累積
  • 中文亂碼:確認伺服器回應 Content-Type: text/plain; charset=UTF-8,客戶端以 new String(bytes, "UTF-8") 解碼
  • 重導向處理:MIDP 實作通常自動處理 301/302,但 POST 重導向行為不一致,建議伺服端避免重導向

總結

GCF 提供了統一、可擴充的網路存取抽象。熟練掌握 HttpConnection 與 ContentConnection 的標頭操作、串流處理、錯誤處理模式,並配合背景執行緒與離線快取策略,即可開發健壯的 J2ME 網路應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
面向建議
執行緒所有網路操作**必須在背景執行緒**進行,避免阻塞 UI 執行緒導致裝置當機
逾時設定J2ME 無標準 API 設定逾時,需自行實作監視執行緒或使用廠商擴充 API
例外處理區分 ConnectionNotFoundException (網路/URL錯誤)、IOException (傳輸錯誤)、SecurityException (權限不足)
資料壓縮伺服端啟用 GZIP,客戶端支援 Accept-Encoding: gzip (需手動解壓)
安全性生產環境強制 HTTPS,驗證伺服器憑證 (MIDP 2.0 支援 HTTPS)
離線支援失敗時回退本地 RMS 快取,提供離線唯讀模式