通过系统属性来指出本地代理服务器地址。 采用的参数有http.proxyHost,http.proxyPort,http.nonProxyHost
以及三个相同的ftp协议开头的代理参数。 java不支持其他任何应用层协议,但如果对所有TCP连接都使用socks代理则可以使用socksProxyHost
和socksProxyPort
系统属性来确定
1 2 3 4 5 6 7 8 9
| System.setProperty("http.proxyHost", "192.168.254.254");
System.setProperty("http.proxyPort", "9000");
System.setProperty("http.nonProxyHost", "java.oreilly.com|xml.oreilly.com");
SocketAddress add = new InetSocketAddress("proxy.example.com", 80); Proxy proxy = new Proxy(Proxy.Type.HTTP, add);
|
虚拟机都有一个为不同连接定位代理服务器的ProxySelector
对象. 默认的ProxySelector
只检查各种系统属性和URL协议,决定如何连接到不同的主机.
下面LocalProxySelect
是一个自己实现的选择器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public void testLocalProxySelect() { ProxySelector select = new LocalProxySelect(); ProxySelector.setDefault(select); }
public static class LocalProxySelect extends ProxySelector {
private List<Object> failed = new ArrayList<>();
@Override public List<Proxy> select(URI uri) {
List<Proxy> result = new ArrayList<>(); if(failed.contains(uri) || "http".equalsIgnoreCase(uri.getScheme())) { result.add(Proxy.NO_PROXY); } else { SocketAddress address = new InetSocketAddress("proxy.example.com", 8000); Proxy proxy = new Proxy(Proxy.Type.HTTP, address); result.add(proxy); } return result; }
@Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { failed.add(uri); }
}
|
下面实现一个socket代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Socket socket = null; try { SocketAddress proxyAddress = new InetSocketAddress("myproxy.example.com", 1080); Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddress); socket = new Socket(proxy); SocketAddress remote = new InetSocketAddress("login.ibiblio.org", 25); socket.connect(remote); } catch (IOException e) { e.printStackTrace(); } finally { if(socket != null) try { socket.close(); } catch (IOException e) { e.printStackTrace(); } }
|