文章目錄
- 簡介
- 使用示例
- GET請求
- POST請求
- HttpURLConnection優化
- 1. 設置合適的超時時間
- 2. 指定字符編碼
- 3. 正確處理響應編碼
- 4. 使用壓縮傳輸(如果適用)
- 5. 關閉連接釋放資源
- 6. 啟用持久連接(Keep-Alive),減少握手開銷
簡介
HttpURLConnection是Java標準庫中的抽象子類,專門用于處理HTTP協議通信。通過URL對象的方法可獲取其實例,支持配置請求方法、超時設置、請求頭管理及響應處理。該抽象類提供對GET、POST等HTTP方法的實現,涵蓋表單提交、輸入輸出流操作及狀態碼判斷等核心功能,廣泛應用于Java應用程序的網絡通信模塊。
使用示例
GET請求
import java.net.*;
import java.io.*;public class HttpExample {public static void main(String[] args) throws IOException {// 創建URL對象URL url = new URL("https://api.example.com/data");// 打開連接(返回URLConnection,需強制轉換為HttpURLConnection)HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 設置請求方法(默認為GET)connection.setRequestMethod("GET");// 配置連接參數(可選)connection.setConnectTimeout(5000); // 連接超時5秒connection.setReadTimeout(5000); // 讀取超時5秒// 發送請求并獲取響應碼int responseCode = connection.getResponseCode();System.out.println("Response Code: " + responseCode);// 處理響應if (responseCode == HttpURLConnection.HTTP_OK) {// 讀取響應數據BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;StringBuilder response = new StringBuilder();while ((line = reader.readLine()) != null) {response.append(line);}reader.close();System.out.println("Response: " + response.toString());}// 斷開連接(釋放資源)connection.disconnect();}
}
POST請求
import java.io.*;
import java.net.*;
import java.util.zip.GZIPInputStream;public class HttpJsonExample {public static void main(String[] args) {try {// 創建URLURL url = new URL("https://api.example.com/users");HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 配置請求connection.setRequestMethod("POST");connection.setDoOutput(true);connection.setConnectTimeout(5000);connection.setReadTimeout(5000);// 設置請求頭connection.setRequestProperty("Content-Type", "application/json");connection.setRequestProperty("Accept", "application/json");connection.setRequestProperty("Accept-Encoding", "gzip");// 寫入請求體String requestBody = "{\"name\":\"Alice\",\"email\":\"alice@example.com\"}";try (OutputStream os = connection.getOutputStream()) {byte[] input = requestBody.getBytes("utf-8");os.write(input, 0, input.length);}// 獲取響應int responseCode = connection.getResponseCode();System.out.println("Response Code: " + responseCode);// 讀取響應內容InputStream inputStream;if (responseCode >= 200 && responseCode < 300) {inputStream = connection.getInputStream();} else {inputStream = connection.getErrorStream();}// 處理壓縮if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) {inputStream = new GZIPInputStream(inputStream);}// 讀取響應文本try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {String line;StringBuilder response = new StringBuilder();while ((line = reader.readLine()) != null) {response.append(line);}System.out.println("Response: " + response.toString());}} catch (IOException e) {e.printStackTrace();}}
}
HttpURLConnection優化
在使用 HttpURLConnection 進行 HTTP 請求時,為了提高請求效率并確保無亂碼,你可以采取以下幾個步驟:
1. 設置合適的超時時間
連接超時 (setConnectTimeout): 設置建立連接的最長時間。
讀取超時 (setReadTimeout): 設置從服務器讀取數據的最長時間。
例如,設置連接超時和讀取超時為5秒和10秒:
HttpURLConnection connection = (HttpURLConnection) new URL("http://example.com").openConnection();
connection.setConnectTimeout(5000); // 5秒
connection.setReadTimeout(10000); // 10秒
2. 指定字符編碼
確保在發送請求和接收響應時使用正確的字符編碼。對于 GET 和 POST 請求,通常在 URL 中或者在請求頭中指定編碼。
對于 GET 請求,URL 應該已經編碼好。
對于 POST 請求,可以在請求頭中設置 Content-Type 并指定字符集,例如:
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
3. 正確處理響應編碼
在讀取響應時,確保使用了正確的字符編碼來解析響應體。通常,響應的編碼可以在響應頭中找到,例如 Content-Type 中的 charset 參數。
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {response.append(line);
}
reader.close();
輔助方法 getCharsetFromContentType 可以從 Content-Type 頭中提取字符集:
private static String getCharsetFromContentType(String contentType) {String charset = null;if (contentType != null && contentType.contains("charset=")) {charset = contentType.substring(contentType.indexOf("charset=") + 8);} else {charset = "UTF-8"; // 默認字符集}return charset;
}
4. 使用壓縮傳輸(如果適用)
如果服務器支持 gzip 壓縮,可以在請求頭中添加 Accept-Encoding 來請求壓縮的響應:
connection.setRequestProperty("Accept-Encoding", "gzip");
5. 關閉連接釋放資源
確保在完成請求后關閉連接,釋放網絡資源。可以使用 try-with-resources 語句來自動管理資源:
try (HttpURLConnection connection = (HttpURLConnection) new URL("http://example.com").openConnection()) {// 設置連接和讀取超時等操作// 獲取響應等操作
} catch (IOException e) {e.printStackTrace();
} // try-with-resources 會自動關閉連接
6. 啟用持久連接(Keep-Alive),減少握手開銷
HTTP/1.1 默認啟用持久連接(Keep-Alive),可復用 TCP 連接處理多次請求(避免重復三次握手),但需正確配置請求頭并合理管理連接生命周期。
// 顯式聲明持久連接(HTTP/1.1默認支持,此配置可增強兼容性)
connection.setRequestProperty("Connection", "keep-alive");// 復用連接:若多次請求同一服務器,可復用當前連接(無需每次調用disconnect())
// 注意:僅在多次請求且服務器支持持久連接時生效
注意:若不再使用連接,需在finally中調用connection.disconnect()釋放資源;但多次請求同一服務器時,可延遲調用以復用連接。
通過上述步驟,你可以提高 HTTP 請求的效率并確保無亂碼。