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

Java 代理模式原理與 HTTP/SOCKS 代理實戰詳解

     編輯:Java 相關知識

代理模式核心原理

代理模式為其他對象提供一個代理以控制對這個對象的訪問。核心角色:

  • Subject(抽象主題):定義真實主題與代理的共同介面。
  • RealSubject(真實主題):實際執行業務邏輯的對象。
  • Proxy(代理):持有 RealSubject 引用,在調用前後添加額外邏輯(權限控制、日誌、緩存、遠程通訊等)。

Java 網絡代理實戰:HTTP 與 SOCKS

場景一:Socket 直連 HTTP 代理

手動構造 HTTP 請求發送給代理服務器:

String proxyHost = "10.1.2.188";
int proxyPort = 80;
try (Socket socket = new Socket(proxyHost, proxyPort);
     OutputStream out = socket.getOutputStream();
     InputStream in = socket.getInputStream()) {

    // 發送 HTTP 請求給代理,目標為百度
    String request = "GET https://www.baidu.com/ HTTP/1.1\r\n" +
                     "Host: www.baidu.com\r\n" +
                     "Connection: close\r\n\r\n";
    out.write(request.getBytes(StandardCharsets.UTF_8));
    out.flush();

    // 讀取響應
    byte[] buffer = new byte[1024];
    int len;
    while ((len = in.read(buffer)) > 0) {
        System.out.write(buffer, 0, len);
    }
}

關鍵點:請求行必須包含完整目標 URL(GET https://target/ HTTP/1.1),並設置 Host 頭。

場景二:URL/HttpURLConnection 設置系統代理

System.setProperty("http.proxyHost", "10.1.2.188");
System.setProperty("http.proxyPort", "80");
// HTTPS 代理
System.setProperty("https.proxyHost", "10.1.2.188");
System.setProperty("https.proxyPort", "443");
// 非代理主機
System.setProperty("http.nonProxyHosts", "localhost|192.168.*");

// 之後直接使用 URL.openConnection() 即可自動走代理
URL url = new URL("https://www.baidu.com");
try (InputStream in = url.openStream()) { /* 讀取 */ }

缺點:全局生效,無法針對單個連接單獨設置。

場景三:Proxy 類精確控制(JDK 1.5+)

// HTTP 代理
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.0.254", 8080));
// SOCKS 代理
// Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("192.168.0.254", 1080));

URL url = new URL("https://www.baidu.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
// 設置認證
Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("user", "pass".toCharArray());
    }
});
try (InputStream in = conn.getInputStream()) { /* 讀取 */ }

優勢:每個連接可獨立設置代理類型、地址、認證,互不干擾。

場景四:NIO SocketChannel 走 HTTP 代理

SocketChannel sc = SocketChannel.open(new InetSocketAddress("10.1.2.188", 80));
sc.write(StandardCharsets.UTF_8.encode("GET https://www.baidu.com/ HTTP/1.1\r\n\r\n"));
ByteBuffer buf = ByteBuffer.allocate(1024);
while (sc.read(buf) != -1) {
    buf.flip();
    System.out.print(StandardCharsets.UTF_8.decode(buf));
    buf.clear();
}
sc.close();

代理模式在框架中的應用

  • Spring AOP:JDK 動態代理 / CGLIB 代理實現切面織入。
  • RPC 框架:Stub 代理隱藏網絡通訊細節。
  • 虛擬代理:延遲加載大對象(如圖片預覽)。
  • 保護代理:權限檢查(如 Jive ForumFactoryProxy)。

總結

理解 HTTP/TCP 協議層級差異是正確使用網絡代理的前提。Socket 層面手動構造請求最靈活但繁瑣;URL/HttpURLConnection 配合 Proxy 類是 Java 應用層最推薦的方式。

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