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

Java HttpURLConnection 發送 GET/POST 請求工具類

     編輯:Java 相關知識

輕量級 HTTP 客戶端

不想引入第三方 Jar 時,JDK 內建 HttpURLConnection 完全足夠應付日常 GET/POST 需求。本文封裝一個線程安全、支援超時、自動釋放資源的工具類。

完整 HttpClient 工具類

package com.example.http;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

public final class HttpClient {

    private HttpClient() {} // 工具類禁止實例化

    /** 發送 GET 請求
     * @param urlString 完整 URL (含查詢參數)
     * @return 回應 Body 字串
     */
    public static String get(String urlString) throws IOException {
        return request(urlString, "GET", null);
    }

    /** 發送 POST 表單請求
     * @param urlString 目標 URL
     * @param params    表單參數 (key=value 格式會自動拼接)
     * @return 回應 Body 字串
     */
    public static String post(String urlString, Map params) throws IOException {
        return request(urlString, "POST", params);
    }

    /** 核心請求邏輯 */
    private static String request(String urlString, String method, Map params) throws IOException {
        HttpURLConnection conn = null;
        try {
            // GET 參數拼接到 URL
            String finalUrl = urlString;
            if ("GET".equalsIgnoreCase(method) && params != null && !params.isEmpty()) {
                finalUrl += (urlString.contains("?") ? "&" : "?") + buildQuery(params);
            }

            URL url = new URL(finalUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(method);
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(10000);
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            conn.setRequestProperty("User-Agent", "Java-HttpClient/1.0");
            conn.setRequestProperty("Accept", "application/json, text/plain, */*");

            // POST 寫入 Body
            if ("POST".equalsIgnoreCase(method) && params != null && !params.isEmpty()) {
                conn.setDoOutput(true);
                try (OutputStream os = conn.getOutputStream()) {
                    os.write(buildQuery(params).getBytes(StandardCharsets.UTF_8));
                }
            }

            // 讀取回應
            int status = conn.getResponseCode();
            InputStream is = (status >= 200 && status < 300) ? conn.getInputStream() : conn.getErrorStream();
            if (is == null) throw new IOException("HTTP " + status + " 無回應流");

            try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) sb.append(line);
                return sb.toString();
            }
        } finally {
            if (conn != null) conn.disconnect(); // 釋放連線
        }
    }

    private static String buildQuery(Map params) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry e : params.entrySet()) {
            if (sb.length() > 0) sb.append('&');
            sb.append(e.getKey()).append('=').append(e.getValue());
        }
        return sb.toString();
    }

    // ---- 測試主程式 ----
    public static void main(String[] args) {
        try {
            // GET 測試
            String getResp = get("https://httpbin.org/get?key=value");
            System.out.println("GET 回應:" + getResp);

            // POST 測試
            Map params = Map.of("username", "admin", "action", "login");
            String postResp = post("https://httpbin.org/post", params);
            System.out.println("POST 回應:" + postResp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用範例 (Java 9+ Map.of)

// 簡單 GET
String html = HttpClient.get("https://api.example.com/users?id=123");

// POST 表單
Map form = new HashMap<>();
form.put("name", "測試");
form.put("email", "test@example.com");
String result = HttpClient.post("https://api.example.com/users", form);

常見問題與解決

擴充建議

  • 🔧 加入重試機制:RetryTemplate 或簡單 for 迴圈 + 指數退避
  • 📦 支援 JSON Body:新增 postJson(url, jsonString),設定 Content-Type: application/json
  • 🍪 Cookie 管理:使用 CookieManager 自動處理 Session
  • 📊 埋點監控:記錄請求耗時、狀態碼、錯誤率上報 Prometheus

這個工具類零依賴、原始碼不足 100 行,放入專案 utils 套件即可直接使用,滿足 90% 簡單 HTTP 呼叫需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題解決
中文亂碼請求/回應均指定 StandardCharsets.UTF_8,確保 Server 端也用 UTF-8
HTTPS 憑證錯誤測試環境可安裝信任憑證,或實作信任所有 TrustManager (僅測試)
大檔案上傳改用 multipart/form-data,需手動組裝 Boundary,建議改用 HttpClient/OkHttp
連線洩漏務必在 finally 呼叫 conn.disconnect(),並關閉所有 Stream
超時不生效檢查伺服器端是否長時間不回應,setReadTimeout 控制讀取等待