[WebMethod]
public string Hello(string str) {
return "你好:" + str;
}
強制 ASP.NET 以 GB2312 解碼請求、編碼回應。
原因:J2ME
HttpConnection簡易呼叫多用 GET,若伺服端僅支援 SOAP/POST,則需完整 SOAP 封裝,大幅增加客戶端代碼量。
package com.sun.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class HttpTest extends MIDlet {
private Display display;
public HttpTest() {
display = Display.getDisplay(this);
}
protected void startApp() {
HttpConnection hc = null;
DataInputStream dis = null;
try {
// 1. 構建 URL,中文參數直接拼接(依賴伺服端 GB2312 解碼)
String url = "https://localhost/WebService1/Service1.asmx/Hello?str=呱呱";
// 2. 開啟連線
hc = (HttpConnection) Connector.open(url);
// 3. 關鍵:設定請求標頭 charset=gb2312
hc.setRequestProperty("Content-Type", "text/html;charset=gb2312");
// 4. 讀取回應
int len = (int) hc.getLength();
dis = new DataInputStream(hc.openInputStream());
if (len > 0) {
byte[] data = new byte[len];
dis.readFully(data);
// 5. 關鍵:回應以 UTF-8 解碼(.NET XML 回應預設 UTF-8)
String content = new String(data, "UTF-8");
Form form = new Form("HTTP Test");
form.append(content); // 顯示含 XML 標籤的原始回應
display.setCurrent(form);
}
} catch (Exception e) {
System.out.println(e);
notifyDestroyed();
} finally {
try { if (dis != null) dis.close(); } catch (Exception ignored) {}
try { if (hc != null) hc.close(); } catch (Exception ignored) {}
}
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
}
| 階段 | 資料形態 | 編碼 | 關鍵代碼/設定 |
|---|---|---|---|
| 客戶端構建 URL | 字串 "呱呱" | Java 內部 Unicode | 無特殊處理 |
| HTTP 請求發送 | 位元組流 | GB2312 (由伺服端要求) | setRequestProperty("Content-Type", "text/html;charset=gb2312") |
| 伺服端接收 | 字串參數 | GB2312 → Unicode | requestEncoding="gb2312" |
| 業務邏輯處理 | 字串 "你好:呱呱" | Unicode | 正常字串操作 |
| XML 序列化回應 | XML 文檔 | UTF-8 (ASP.NET 預設) | responseEncoding="gb2312" 僅影響非 XML 回應 |
| 客戶端讀取 | 位元組陣列 | 原始 UTF-8 位元組 | new String(data, "UTF-8") |
| 顯示 | 字串 | Unicode → 螢幕字型 | MIDP 實現自動處理 |
.NET Web Service 回應為 SOAP XML 格式:
你好:呱呱
J2ME 可用 kXML、NanoXML、或簡易字串截取解析 <string> 節點內容。
OutputStream.write(bytes),伺服端 Request.BinaryReadDataOutputStream.writeUTF() / DataInputStream.readUTF()(修改版 UTF-8),零配置零亂碼IOException、CertificateException (HTTPS)、逾時,給用戶友好提示| 現象 | 原因 | 修正 |
|---|---|---|
| 中文參數變亂碼 | 未設定 Content-Type charset | 加上 charset=gb2312 |
| 回應中文變問號 | 用 ISO-8859-1 解碼 UTF-8 位元組 | new String(data, "UTF-8") |
| HTTP 405 Method Not Allowed | .NET 未開啟 HttpGet/HttpPost | web.config 加入 protocols 區段 |
| 模擬器能連,真機不能 | 真機無公網 IP/防火牆/APN 限制 | 確認 APN 設定、伺服端公網可達、使用 HTTPS |
J2ME 呼叫 .NET Web Service 的核心難點在於編碼協議不一致。通過 web.config 統一伺服端編碼、HttpConnection.setRequestProperty 宣告客戶端編碼、new String(bytes, "UTF-8") 正確解碼回應,三步驟徹底解決中文亂碼。此模式同樣適用於 J2ME 對接 Java/PHP/Python 等任意後端服務——明確協議、顯式聲明、嚴格驗證,是跨平台整合的黃金法則。