1. 简介
许多系统通过代理服务器访问Web,有时还会访问Internet的其他非HTTP部分。代理服务器接受从本地客户端服务器的请求。代理服务器向远程服务器发出请求,再将结果转发回本地客户端。有时这样做是为了安全,如防止远程主机了解关于本地网络配置的秘密细节。另外一些情况,这样做是为了通过过滤出站请求,限制可以浏览的网站。而还有一些情况则纯粹是出于性能的考虑,这样允许多个用户从本地缓存中获取同样的一些经常访问的文档,二不是重复从远程主机下载。基于URL类的java程序可以使用大多数常见的代理服务器和协议。事实上,正是出于这个原因,你要选择使用URL类,而不是在原始socket之上处理你自己的HTTP或其他客户端。
2. 系统属性
如果要指定纯粹的HTTP代理,则将http.proxyHost设置为代理服务器的域名或IP地址,将http.proxyPort设置为代理服务器的端口(默认为80)。还有一些其它方法,包括在Java代码中调用System.setProperty(),或在启动项中设置-D选项。
public class QuizCardBuilder {
public static void main(String[] args) throws UnsupportedEncodingException {
System.setProperty("http:proxyHost","192.168.254.254");
System.setProperty("http.proxyPort","9000");
System.setProperty("http.nonProxyHosts","java.oreilly.com|xml.orelly.com")
}
}
如果希望一台主机不被代理,而是要直接连接目标服务器,则要把http.nonProxyHosts系统属性设置为其主机名或IP地址。如果多个主机不需要代理,可以用竖线隔开这些主机名。“*”表示某个特定的所有主机都不需要代理。
如果要对ftp设置,一样的操作即可
Java不支持任何其他应用层协议,但是如果对所有的TCP连接都使用传输层SOCKS代理,可以用socksProxyHost和socksProxyPort系统属性来确定。Java对SOCKS没有提供禁止代理选项,这是一个全有或全无的选择。
3. Proxy类
在Java中,java.net.Proxy类用于表示代理服务器。代理服务器充当客户端和目标服务器之间的中间人,它接收来自客户端的请求,并将其转发给目标服务器,然后将响应返回给客户端。Proxy类提供了一种封装代理服务器的方式,以便在网络通信中使用代理。Proxy类允许从Java程序中对代理服务器进行更细粒度的控制。确切的说,它允许你为不同的远程主机选择不同的代理服务器,它有三种代理模式,分别用Proxy.Type枚举中的三个常量表示:
- Proxy.Type.DIRECT
- Proxy.Type.HTTP
- Proxy.Type.SOCKS
除了类型之外,关于代理的其它重要信息包括它的地址和端口,用SocketAddress对象表示。
public class QuizCardBuilder {
public static void main(String[] args) {
try {
// 创建代理服务器地址
InetSocketAddress proxyAddress = new InetSocketAddress("proxy.example.com", 8080);
// 创建代理实例
Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
// 创建目标URL
URL url = new URL("http://www.example.com");
// 打开连接并设置代理
HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
// 发送请求并读取响应
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
// 关闭连接
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. ProxySelector类
java.net.ProxySelector是Java中的一个类,用于选择适当的代理服务器。在Java中,可以使用ProxySelector类来设置和获取代理选择器,并使用它来选择与特定URL或协议相关联的代理服务器。ProxySelector类提供了以下主要方法:
-
getDefault():静态方法,返回默认的代理选择器。默认情况下,它使用系统属性来确定代理设置。
-
setDefault(ProxySelector ps):静态方法,设置默认的代理选择器。
-
select(URI uri):选择与指定URI相关联的代理服务器。根据传递的URI,select()方法返回一个包含Proxy对象的List,其中每个Proxy对象表示一个可用的代理服务器。
-
connectFailed(URI uri, SocketAddress sa, IOException ioe):通知代理选择器连接失败的情况。这个方法允许代理选择器调整代理的偏好顺序。
import java.io.IOException;
import java.net.*;
public class ProxySelectorTest {
public static void main(String[] args) {
try {
// 创建URL
URL url = new URL("http://www.example.com");
// 自定义代理选择器
ProxySelector proxySelector = new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
// 返回一个包含单个HTTP代理的列表
List<Proxy> proxies = new ArrayList<>();
proxies.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080)));
return proxies;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// 处理连接失败的情况
System.out.println("Failed to connect to proxy: " + sa);
}
};
// 设置自定义的代理选择器
ProxySelector.setDefault(proxySelector);
// 选择代理服务器
URI uri = url.toURI();
List<Proxy> proxies = proxySelector.select(uri);
// 输出可用的代理服务器
for (Proxy proxy : proxies) {
System.out.println("Proxy: " + proxy);
SocketAddress address = proxy.address();
if (address instanceof InetSocketAddress) {
InetSocketAddress proxyAddress = (InetSocketAddress) address;
System.out.println("Proxy Hostname: " + proxyAddress.getHostName());
System.out.println("Proxy Port: " + proxyAddress.getPort());
}
}
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们创建了一个ProxySelector匿名内部类,重写了select()方法和connectFailed()方法,以提供自定义的代理选择逻辑。在select()方法中,我们返回一个包含单个HTTP代理的列表,代理服务器的地址是proxy.example.com,端口号是8080。在connectFailed()方法中,我们处理连接失败的情况。然后,我们使用ProxySelector.setDefault()方法设置自定义的代理选择器。接下来,我们将URL转换为URI,并使用select()方法选择与URI相关联的代理服务器。最后,我们遍历返回的代理服务器列表,并输出每个代理服务器的相关信息。请注意,上述代码中的代理服务器地址和端口号是示例,需要根据实际情况进行修改,以便进行测试。这个示例代码用于演示如何自定义代理选择器,并使用ProxySelector类选择代理服务器。根据实际需求,可以根据特定的逻辑和条件编写自定义的代理选择器,以满足具体的代理需求。