J2SE 5.0 大幅增強了代理伺服器控制能力,支援 HTTP、HTTPS、FTP、SOCKS 等多種協定的獨立配置,並可指定繞過代理的主機清單,功能媲美瀏覽器代理設定。本文系統整理三種配置方式並提供完整程式碼範例。
-D 參數或程式中 System.setProperty() 設定。Proxy 物件,針對單一連線指定代理。透過 System.getProperties() 設定以下屬性:
| 屬性名稱 | 說明 |
|---|---|
| http.proxyHost / http.proxyPort | HTTP 代理主機與埠 |
| http.nonProxyHosts | 不經代理的主機,支援 * 萬用字元,多值用 | 分隔 |
| https.proxyHost / https.proxyPort | HTTPS 代理(無獨立 nonProxyHosts,遵循 HTTP 設定) |
| ftp.proxyHost / ftp.proxyPort / ftp.nonProxyHosts | FTP 代理設定 |
| socksProxyHost / socksProxyPort | SOCKS 代理設定 |
public void setLocalProxy() {
Properties prop = System.getProperties();
prop.setProperty("http.proxyHost", "10.10.0.96");
prop.setProperty("http.proxyPort", "8080");
prop.setProperty("http.nonProxyHosts", "localhost|10.10.*");
prop.setProperty("https.proxyHost", "10.10.0.96");
prop.setProperty("https.proxyPort", "443");
prop.setProperty("ftp.proxyHost", "10.10.0.96");
prop.setProperty("ftp.proxyPort", "2121");
prop.setProperty("ftp.nonProxyHosts", "localhost|10.10.*");
prop.setProperty("socksProxyHost", "10.10.0.96");
prop.setProperty("socksProxyPort", "1080");
}
public void removeLocalProxy() {
Properties prop = System.getProperties();
String[] keys = {"http.proxyHost", "http.proxyPort", "http.nonProxyHosts",
"https.proxyHost", "https.proxyPort",
"ftp.proxyHost", "ftp.proxyPort", "ftp.nonProxyHosts",
"socksProxyHost", "socksProxyPort"};
for (String key : keys) prop.remove(key);
}
不想影響全域系統屬性時,可建立 Proxy 物件傳給 URL.openConnection(Proxy):
public Proxy getProxy(Proxy.Type type, String host, int port) {
SocketAddress addr = new InetSocketAddress(host, port);
return new Proxy(type, addr);
}
// 使用範例
Proxy socksProxy = getProxy(Proxy.Type.SOCKS, "10.10.0.96", 1080);
URLConnection conn = url.openConnection(socksProxy);
public class NetProxy {
// ... 包含上述 setLocalProxy, removeLocalProxy, getProxy 方法 ...
public void showHttpProxy(Object... proxy) {
try {
URL url = new URL("https://blog.csdn.com/smallnest");
URLConnection conn = (proxy.length == 0) ?
url.openConnection() : url.openConnection((Proxy)proxy[0]);
conn.setConnectTimeout(3000);
try (InputStream in = conn.getInputStream()) {
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
System.out.print(new String(buf, 0, len));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
NetProxy np = new NetProxy();
np.setLocalProxy(); // 方式一:系統屬性
np.showHttpProxy(); // 使用系統代理
// np.removeLocalProxy(); // 方式二:清除系統屬性改用 Proxy 物件
// np.showHttpProxy(np.getProxy(Proxy.Type.SOCKS, "10.10.0.96", 1080));
}
}
繼承 ProxySelector 並覆寫 select(URI uri) 方法,可根據目標位址、負載狀態動態回傳代理清單,實現:
註冊方式:ProxySelector.setDefault(new MyProxySelector())。
J2SE 5.0 提供了從簡單的系統屬性到進階的 ProxySelector 完整代理配置體系,滿足從單機應用到企業級分散式系統的各種代理需求。