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

Java 應用程式代理配置完整指南:HTTP、FTP、SOCKS 協議實戰

     編輯:Java 相關知識

企業網路環境普遍部署代理伺服器以管控對外存取。Java 應用若需通過代理訪問外部資源,需正確配置系統屬性與認證機制。本文詳解 HTTP/HTTPS、FTP、SOCKS 代理配置細節、認證處理與常見坑點。

核心系統屬性

JVM 透過 System.setProperty() 或啟動參數 -D 設定代理屬性,必須在建立網路連線前配置。

HTTP/HTTPS 代理

// 基礎配置
System.setProperty("http.proxySet", "true");
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");

// 非代理主機清單(支援萬用字元)
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|*.internal.com");

FTP 代理

System.setProperty("ftp.proxySet", "true");
System.setProperty("ftp.proxyHost", "proxy.example.com");
System.setProperty("ftp.proxyPort", "2121");

SOCKS 代理 (SOCKS4/5)

System.setProperty("socksProxySet", "true");
System.setProperty("socksProxyHost", "proxy.example.com");
System.setProperty("socksProxyPort", "1080"); // SOCKS 預設 1080
// JDK 1.5+ 支援 SOCKS5 驗證
System.setProperty("java.net.socks.username", "user");
System.setProperty("java.net.socks.password", "pass");

代理認證處理

方案一:Authenticator 全域認證 (推薦)

Authenticator.setDefault(new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("username", "password".toCharArray());
    }
});

適用於 HTTP/HTTPS/FTP/SOCKS 統一認證,程式碼無侵入性。

方案二:URLConnection 單點認證

URL url = new URL("https://target.com/resource");
URLConnection conn = url.openConnection();
String auth = "username:password";
String encoded = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
conn.setRequestProperty("Proxy-Authorization", "Basic " + encoded);

注意:Header 值必須包含 "Basic " 前綴,且使用標準 Base64 編碼(JDK 8+ 使用 java.util.Base64,避免使用內部類 sun.misc.BASE64Encoder)。

進階場景與坑點

1. 不同協議不同代理

HTTP、HTTPS、FTP 可分別設定不同代理主機/埠,互不干擾。

2. 程式碼動態切換代理

系統屬性為 JVM 全域生效,若需執行緒級別隔離,需自行實現 ProxySelector 或使用 Apache HttpClient 等支援細粒度代理控制的庫。

3. JDK 版本差異

  • JDK 1.1.x:系統屬性代理可能失效,需使用 new URL(protocol, host, port, file) 建構子指定代理
  • JDK 8+:移除 sun.misc.BASE64Encoder,改用 java.util.Base64
  • JDK 11+:HTTP Client API 原生支援代理配置(HttpClient.newBuilder().proxy(ProxySelector.of(...)))

4. 非代理主機匹配規則

http.nonProxyHosts 支援 | 分隔、* 萬用字元,不支援 CIDR 表示法。主機名匹配不區分大小寫。

5. 代理繞過本地回環

預設情況下 JVM 會嘗試對本地位址走代理,建議明確加入:

System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|::1");

程式碼範例:完整配置類

public class ProxyConfig {
    public static void configure(HttpProxyConfig config) {
        // HTTP/HTTPS
        setProxy("http", config.getHost(), config.getPort());
        setProxy("https", config.getHost(), config.getPort());
        
        // 非代理清單
        if (config.getNonProxyHosts() != null) {
            System.setProperty("http.nonProxyHosts", config.getNonProxyHosts());
        }
        
        // 認證
        if (config.requiresAuth()) {
            Authenticator.setDefault(new ProxyAuthenticator(config.getUser(), config.getPassword()));
        }
    }
    
    private static void setProxy(String protocol, String host, int port) {
        System.setProperty(protocol + ".proxySet", "true");
        System.setProperty(protocol + ".proxyHost", host);
        System.setProperty(protocol + ".proxyPort", String.valueOf(port));
    }
}

驗證代理生效

// 簡單測試
URL url = new URL("https://httpbin.org/ip");
try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
    System.out.println("代理生效,回應 IP: " + in.readLine());
}

回應 IP 應為代理伺服器出口 IP,而非本機公網 IP。

總結

Java 代理配置核心在於早期設定系統屬性與正確處理認證 Header。現代專案建議採用 Apache HttpClient、OkHttp 或 JDK 11+ HttpClient,享受更靈活的代理控制、連線池管理與非同步支援。排查代理問題時,優先檢查:屬性拼寫、設定時機、認證格式、非代理清單、防火牆/代理伺服器端日誌。

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