HTTP 1.1 允許伺服器以 302 狀態碼指示資源臨時移動,新位置在 Location 標頭。但移動設備實作差異極大:有的自動追蹤、有的回傳 null、有的將新 URL 藏在回應主體。本文提供健壯的跨設備重定向處理代碼模式。
// 簡單寫法在部分設備會崩潰
Connection c = (HttpConnection) Connector.open(uri);
int status = c.getResponseCode();
String newUri = c.getHeaderField("Location"); // 可能為 null
if (status == 302) {
c.close();
c = (HttpConnection) Connector.open(newUri); // NPE 或無效 URL
}
Location 標頭含新 URL,客戶端應手動重導。Location 解析失敗:回傳 null,新 URL 可能在回應主體(HTML meta refresh 或 JS)。getResponseCode() 直到變 200。
HttpConnection httpConnection = (HttpConnection) Connector.open(uri);
int status = httpConnection.getResponseCode();
String redirection = httpConnection.getHeaderField("Location");
if (status == HttpConnection.HTTP_TEMP_REDIRECT) { // 302
if (redirection != null) {
// 標準流程:關閉舊連線,開新連線
httpConnection.close();
httpConnection = (HttpConnection) Connector.open(redirection);
status = httpConnection.getResponseCode();
// 遞歸或迴圈處理多層重定向(建議限制最大層數,如 5 次)
} else {
// 嘗試從回應主體解析 Location
// 這裡需讀取 InputStream,用字串搜尋 "Location" 或 meta refresh
// 為簡潔略去解析代碼,若解析成功 redirection = parsedUrl
if (redirection != null) {
httpConnection.close();
httpConnection = (HttpConnection) Connector.open(redirection);
status = httpConnection.getResponseCode();
} else {
// 兜底:輪詢等待狀態碼變 200(部分設備內部已完成重導)
long startWait = System.currentTimeMillis();
while (System.currentTimeMillis() - startWait < 1000) {
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
int newStatus = httpConnection.getResponseCode();
if (newStatus == HttpConnection.HTTP_OK) {
status = HTTP_OK;
break;
}
}
if (status != HttpConnection.HTTP_OK) {
throw new IOException("重定向失敗:無 Location 且狀態碼未轉 200");
}
}
}
}
// 此處 status 應為 200,繼續正常處理回應
// ...
close(),釋放無線電資源。RFC 2616 Section 10.3.3:https://www.ietf.org/rfc/rfc2616.txt