| 屬性名 | 說明 | 示例 |
| http.proxyHost | 代理服務器主機名或 IP | 192.168.1.111 |
| http.proxyPort | 代理服務器端口 | 80 / 3128 / 8080 |
| http.nonProxyHosts | 繞過代理的主機模式(可選) | localhost|127.0.0.1|*.internal.com |
| https.proxyHost | HTTPS 代理主機(獨立配置) | proxy.company.com |
| https.proxyPort | HTTPS 代理端口 | 443 / 8443 |
二、完整代碼示例
import java.util.Properties;
import java.net.*;
import java.io.*;
public class TestHttpProxy {
public static void main(String[] args) {
String targetUrl = "https://java.sun.com/index.html";
// 1. 設置代理系統屬性(全局生效,影響後續所有 URL 連接)
Properties props = System.getProperties();
props.put("http.proxyHost", "192.168.1.111");
props.put("http.proxyPort", "80");
// 可選:內網地址直連
props.put("http.nonProxyHosts", "localhost|127.0.0.1|192.168.*");
try {
// 2. 正常創建 URL 與連接,無感知代理
URL url = new URL(targetUrl);
System.out.println("URL: " + url);
URLConnection conn = url.openConnection();
System.out.println("Connection: " + conn);
// 3. 讀取響應流
try (InputStream is = url.openStream()) {
int ch;
while ((ch = is.read()) != -1) {
System.out.print((char) ch);
}
}
System.out.println("\nOK: Successfully fetched via proxy.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、進階用法:程序化控制(不污染全局屬性)
// 僅對特定連接使用代理
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.1.111", 80));
URL url = new URL("https://java.sun.com/index.html");
URLConnection conn = url.openConnection(proxy); // JDK 1.5+
// 設置連接超時、讀取超時
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
- JDK 1.5+ 推薦使用
Proxy 對象,線程安全、粒度可控
- 避免修改
System.getProperties() 影響其他模塊
四、認證代理處理
// 代理需要用戶名密碼
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("proxyUser", "proxyPass".toCharArray());
}
});
配合 http.proxyUser/http.proxyPassword(非標準,部分實現支持)或上述 Authenticator 模式。
五、常見問題排查
| 現象 | 可能原因 | 解決方案 |
| Connection refused | 代理 IP/端口錯誤、代理服務未啟動 | telnet 驗證連通性、確認代理配置 |
| 407 Proxy Authentication Required | 代理需認證未提供 | 設置 Authenticator 或 Proxy-Authorization Header |
| HTTPS 無法訪問 | 未配置 https.proxyHost/Port | 單獨設置 HTTPS 代理屬性 |
| 內網地址也走代理 | 未設置 nonProxyHosts | 添加 http.nonProxyHosts=localhost|192.168.* |
| 獲取不到響應 | 代理返回非標準狀態、流未關閉 | 檢查連接超時設置、確保流正確關閉 |
六、最佳實踐建議
- 配置外部化:代理參數放入配置文件/環境變量,啟動時注入
-Dhttp.proxyHost=... -Dhttp.proxyPort=...
- 區分 HTTP/HTTPS:分別設置
http.* 与 https.* 屬性
- 優先用 Proxy API:JDK 1.5+ 項目避免全局屬性污染
- 超時保護:必須設置連接/讀取超時,防止掛死
- 單元測試 Mock:使用
MockWebServer (OkHttp) 或 WireMock 模擬代理行為
七、結語
java.net.URL 通過系統屬性或 Proxy API 實現 HTTP 代理透明接入,是 Java 網絡編程的基礎技能。掌握 http.proxyHost/Port、nonProxyHosts、Authenticator、Proxy 對象等完整工具鏈,能讓企業級應用靈活適應複雜網絡拓撲,安全、可控地訪問互聯網資源。
- 上一篇文章: JBuilder 2005 Struts 遷移實戰:以 Action 控制器替換 switch.jsp 並新增圖書管理模塊
- 下一篇文章: CORBA 與 Java 技術選型指南:在規則與自由間尋找企業信息系統的平衡點
Copyright ©
程式碼之家 All Rights Reserved