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

HttpURLConnection 中 setDoOutput 與 setDoInput 完全指南

     編輯:Java 相關知識

API 官方定義

setDoInput(boolean)

默認 true。表示意圖從 URL 連接讀取數據(即調用 getInputStream())。設為 false 可節省資源,若僅發送數據不需響應體。

setDoOutput(boolean)

默認 false。表示意圖向 URL 連接寫入數據(即調用 getOutputStream())。POST/PUT/PATCH 等需請求體的方法必須設為 true。

實戰決策表

HTTP 方法需請求體?需響應體?setDoOutputsetDoInput
GET否是false (默認)true (默認)
POST是通常是truetrue (默認)
PUT是通常是truetrue (默認)
DELETE否/是視情況視情況視情況
HEAD否否(僅頭)falsefalse

代碼範例

標準 POST 請求

URL url = new URL("https://api.example.com/users");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true); // 必須!否則 getOutputStream() 拋異常
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

try (OutputStream os = conn.getOutputStream()) {
    String json = "{\"name\":\"John\",\"age\":30}";
    os.write(json.getBytes(StandardCharsets.UTF_8));
}

int code = conn.getResponseCode();
try (InputStream is = code >= 400 ? conn.getErrorStream() : conn.getInputStream()) {
    String response = new String(is.readAllBytes(), StandardCharsets.UTF_8);
    System.out.println(response);
}

純發送無響應(如異步通知、Webhook)

conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(false); // 節省輸入流資源
conn.getOutputStream().write(payload);
int code = conn.getResponseCode(); // 僅檢查狀態碼
// 不調用 getInputStream()/getErrorStream()

常見錯誤與排查

  1. POST 請求報 java.net.ProtocolException: Cannot write output after reading input
    原因:調用 getInputStream() 後再調用 getOutputStream()。
    修正:先寫出流,再讀入流。
  2. 忘記 setDoOutput(true) 導致 java.net.ProtocolException: DoOutput is false
    任何需寫入請求體的方法(POST/PUT/PATCH)必須顯式設為 true。
  3. GET 請求誤設 setDoOutput(true)
    雖不報錯,但會發送空請求體,違反 HTTP 語義,部分伺服器拒絕。

進階提示

  • setFixedLengthStreamingMode(len) 或 setChunkedStreamingMode(len) 可避免大請求體緩衝到堆內存
  • 連接複用:設置 http.keepAlive=true(默認),配合連接池(如 Apache HttpClient、OkHttp)更高效
  • 超時控制:setConnectTimeout(5000)、setReadTimeout(10000) 必須設置,防止掛死

核心口訣:要寫出流必開 DoOutput,要讀入流默認 DoInput,先出後入不倒序。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved