| 包/類 | 核心功能 | 適用場景 |
|---|---|---|
java.net.URL | 統一資源定位符封裝、openStream()/openConnection() | 簡單 HTTP/HTTPS/FTP/JAR 資源讀取 |
java.net.URLConnection | 通用連接配置 (超時、請求頭、輸出流) | 需控制請求參數、POST 表單、Cookie 管理 |
java.net.HttpURLConnection | HTTP 專用功能 (方法、響應碼、重定向策略) | REST API 調用、需精細 HTTP 控制 |
java.net.URI | 語法解析、規範化、相對路徑解析 (不打開連接) | URI 構建、驗證、模板展開 |
java.net.Socket / ServerSocket | TCP 套接字、阻塞 I/O | 自定義協議、舊系統集成 |
java.nio.channels.SocketChannel | 非阻塞 I/O、Selector 多路複用 | 高併發服務端、Netty 等框架基礎 |
public String fetchText(String urlString) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new URL(urlString).openStream(), StandardCharsets.UTF_8))) {
return reader.lines().collect(Collectors.joining("\n"));
}
}
public void downloadFile(String urlString, Path dest) throws IOException {
try (InputStream in = new URL(urlString).openStream()) {
Files.copy(in, dest, StandardCopyOption.REPLACE_EXISTING);
}
}
// Swing
ImageIcon icon = new ImageIcon(new URL("https://example.com/img.png"));
// 或
Image img = ImageIO.read(new URL("https://example.com/img.png"));
// JavaFX
Image fxImg = new Image("https://example.com/img.png");
public String postJson(String urlString, String json) throws IOException {
HttpURLConnection conn = (HttpURLConnection) new URL(urlString).openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
try (OutputStream os = conn.getOutputStream()) {
os.write(json.getBytes(StandardCharsets.UTF_8));
}
int status = conn.getResponseCode();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(status < 400 ? conn.getInputStream() : conn.getErrorStream(), StandardCharsets.UTF_8))) {
return reader.lines().collect(Collectors.joining("\n"));
}
}
原生 HttpURLConnection 無連接池,高併發必須用成熟客戶端:
// Apache HttpClient 5.x
CloseableHttpClient client = HttpClients.custom()
.setMaxConnTotal(200)
.setMaxConnPerRoute(50)
.evictIdleConnections(Duration.ofSeconds(30))
.build();
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
try (ClassicHttpResponse resp = client.executeOpen(null, post, HttpClientContext.create())) {
return EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
}
public void downloadWithResume(String url, Path dest) throws IOException {
long existing = Files.exists(dest) ? Files.size(dest) : 0;
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
if (existing > 0) {
conn.setRequestProperty("Range", "bytes=" + existing + "-");
}
// 檢查響應碼 206 Partial Content
// 以 append 模式寫入文件
}
// 全局代理 (JVM 參數)
-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -Dhttp.nonProxyHosts="localhost|*.internal"
// 程序化代理 (單連接)
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy", 8080));
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(proxy);
// 認證
Authenticator.setDefault(new Authenticator() {
@Override protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "pass".toCharArray());
}
});
// 生產環境:正規 CA 證書,無需特殊配置
// 測試環境:信任所有證書 (僅測試!)
TrustManager[] trustAll = { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] c, String a) {}
public void checkServerTrusted(X509Certificate[] c, String a) {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAll, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((h, s) -> true);
| 陷阱 | 原因 | 解決 |
|---|---|---|
| URL 中文參數亂碼 | 編碼不一致 (瀏覽器/服務器/JVM) | 統一 UTF-8,URLEncoder.encode(param, "UTF-8") |
| 重定向循環 | 服務器誤配置 | conn.setInstanceFollowRedirects(false) 手動處理 |
| 超時設置無效 | 僅設置連接超時無讀取超時 | 雙超時必設:setConnectTimeout/setReadTimeout |
| 流未關閉導致連接洩漏 | 異常路徑未 close | try-with-resources 包裹 InputStream/OutputStream |
| User-Agent 被屏蔽 | 默認 "Java/版本" 被防火牆攔截 | conn.setRequestProperty("User-Agent", "MyApp/1.0") |
新項目 首選:
Java 網絡編程從 URL.openStream() 簡單讀取,到 HttpURLConnection 精細控制,再到成熟客戶端庫 (OkHttp/HttpClient) 的生產級能力。核心功課:**編碼統一 UTF-8、雙超時必設、流資源 try-with-resources、User-Agent 自定義、證書驗證不跳過**。理解 TCP/HTTP 基礎協議,選擇合適抽象層級,是構建健壯網絡應用的前提。