Java 標準庫提供 java.net.HttpURLConnection,無第三方依賴即可完成 HTTP 請求。核心流程:
new URL(urlStr) 解析地址(可能拋 MalformedURLException);url.openConnection() 獲取連接對象(尚未建立 TCP 連接);HttpURLConnection 設置請求屬性、超時、重定向策略;connect() / getInputStream() 真正發起請求(可能拋 IOException);finally 關閉流、斷開連接 disconnect()。public final class SimpleHttpClient {
private static final int DEFAULT_TIMEOUT_MS = 10_000;
private static final String USER_AGENT = "Mozilla/5.0 (compatible; JavaBot/1.0)";
private SimpleHttpClient() {}
/** 同步 GET,返回響應體字符串 */
public static String get(String urlStr) throws IOException {
return get(urlStr, DEFAULT_TIMEOUT_MS, null);
}
/** 完整參數版 */
public static String get(String urlStr, int timeoutMs, Map headers) throws IOException {
HttpURLConnection conn = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(timeoutMs);
conn.setReadTimeout(timeoutMs);
conn.setInstanceFollowRedirects(true); // 自動跟隨 301/302
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); // 支持壓縮
if (headers != null) headers.forEach(conn::setRequestProperty);
int code = conn.getResponseCode();
if (code != HttpURLConnection.HTTP_OK) {
throw new HttpException("HTTP " + code + " " + conn.getResponseMessage());
}
// 自動處理 GZIP
InputStream is = conn.getInputStream();
String encoding = conn.getContentEncoding();
if ("gzip".equalsIgnoreCase(encoding)) is = new GZIPInputStream(is);
// 編碼檢測:優先 Content-Type charset,回退 UTF-8
String charset = extractCharset(conn.getContentType());
return IOUtils.toString(is, Charset.forName(charset));
} finally {
if (conn != null) conn.disconnect(); // 釋放連接回池
}
}
private static String extractCharset(String contentType) {
if (contentType == null) return "UTF-8";
Matcher m = Pattern.compile("charset=([^\\s;]+)").matcher(contentType);
return m.find() ? m.group(1).toUpperCase() : "UTF-8";
}
/** 簡易異常類 */
public static class HttpException extends IOException {
public HttpException(String msg) { super(msg); }
}
}
commons-io commons-io 2.15.1
若不想引入依賴,自寫 toString(InputStream, Charset) 只需 10 行循環讀取代碼。
try {
String html = SimpleHttpClient.get("https://httpbin.org/html");
System.out.println("頁面長度:" + html.length());
// 此處可接 JSoup 解析、正則提取等後續處理
} catch (SimpleHttpClient.HttpException e) {
System.err.println("業務錯誤:" + e.getMessage());
} catch (IOException e) {
System.err.println("網絡/IO 錯誤:" + e.getMessage());
}
| 場景 | HttpURLConnection 局限 | 升級方案 |
|---|---|---|
| Cookie 會話保持 | 手動管理 CookieManager | OkHttp 自動 CookieJar |
| 連接池複用 | 無連接池,每次新建 | OkHttp ConnectionPool / HttpClient 5 |
| HTTP/2 支持 | 不支持 | OkHttp / Jetty Client |
| 異步非阻塞 | 阻塞 IO | Netty / Vert.x / WebClient |
| JS 動態渲染 | 無法執行 JS | Selenium / Playwright / Puppeteer |
HttpURLConnection 是 Java 標準庫的輕量級 HTTP 客戶端,適合簡單同步 GET/POST、無高併發、無複雜會話的場景。生產環境建議遷移至 OkHttp 或 Apache HttpClient 5,獲得連接池、攔截器、HTTP/2、異步等企業級能力。