Java Proxy代理服务器编程(附带实例)
代理服务器(Proxy Server)的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站,是个人网络和 Internet 服务商之间的中间代理机构,负责转发合法的网络信息,并对转发进行控制和登记。
随着 Internet 与 Intranet 的飞速发展,作为连接 Internet 与 Intranet 的桥梁,代理服务器在实际应用中发挥着极其重要的作用。
Proxy 代表一个代理服务器,可以在打开 URLConnection 连接时指定 Proxy,创建 Socket 连接时也可以指定 Proxy。
ProxySelector 代表一个代理选择器,它提供了对代理服务器更加灵活地控制,可以对 HTTP、HTTPS、FTP、SOCKS 等进行分别设置,而且还可以设置不需要通过代理服务器的主机和地址。通过使用 ProxySelector,可以实现与在 Internet Explorer、Firefox 等软件中设置代理服务器类似的效果。
浏览器中代理服务器的设置页面如下图所示:

图 1 Internet Explorer设置代理服务器
Proxy 有一个构造器,用于创建表示代理服务器的 Proxy 对象:
一旦创建了 Proxy 对象之后,程序就可以在使用 URLConnection 打开连接时,或者创建 Socket 连接时传入一个 Proxy 对象,作为本次连接所使用的代理服务器。
其中,URL 类包含了一个 URLConnection openConnection(Proxy proxy) 方法,该方法使用指定的代理服务器来打开连接;而 Socket 类则提供了一个 Socket(Proxy proxy) 构造器,该构造器使用指定的代理服务器创建一个没有连接的 Socket 对象。
接下来,以 URLConnection 为例来介绍如何在 URLConnection 中使用代理服务器。
ProxySelector 类代表一个代理选择器,它本身是一个抽象类,程序无法创建它的实例,开发者可以考虑继承 ProxySelector 类来实现自己的代理选择器。
实现 ProxySelector 类的步骤非常简单,程序只要定义一个继承 ProxySelector 类的类,并让该类实现如下两个抽象方法:
实现了自己的 ProxySelector 类之后,调用 ProxySelector 类的 setDefault(ProxySelector ps) 静态方法来注册该代理选择器即可。
接下来,通过案例来演示如何让自定义的 ProxySelector 类来自动选择代理服务器。
随着 Internet 与 Intranet 的飞速发展,作为连接 Internet 与 Intranet 的桥梁,代理服务器在实际应用中发挥着极其重要的作用。
Java Proxy创建网络连接
Java 在 java.net 包下提供了 Proxy 和 ProxySelector 两个类。Proxy 代表一个代理服务器,可以在打开 URLConnection 连接时指定 Proxy,创建 Socket 连接时也可以指定 Proxy。
ProxySelector 代表一个代理选择器,它提供了对代理服务器更加灵活地控制,可以对 HTTP、HTTPS、FTP、SOCKS 等进行分别设置,而且还可以设置不需要通过代理服务器的主机和地址。通过使用 ProxySelector,可以实现与在 Internet Explorer、Firefox 等软件中设置代理服务器类似的效果。
浏览器中代理服务器的设置页面如下图所示:

图 1 Internet Explorer设置代理服务器
Proxy 有一个构造器,用于创建表示代理服务器的 Proxy 对象:
Proxy(Proxy.Type type, SocketAddress socketAddress)
- socketAddress 指定代理服务器的地址;
-
type 表示该代理服务器的类型,该服务器类型有如下 3 种:
- Proxy.Type.DIRECT:表示直接连接,不使用代理。
- Proxy.Type.HTTP:表示支持高级协议代理,如HTTP或FTP。
- Proxy.Type.SOCKS:表示SOCKS(V4或V5)代理。
一旦创建了 Proxy 对象之后,程序就可以在使用 URLConnection 打开连接时,或者创建 Socket 连接时传入一个 Proxy 对象,作为本次连接所使用的代理服务器。
其中,URL 类包含了一个 URLConnection openConnection(Proxy proxy) 方法,该方法使用指定的代理服务器来打开连接;而 Socket 类则提供了一个 Socket(Proxy proxy) 构造器,该构造器使用指定的代理服务器创建一个没有连接的 Socket 对象。
接下来,以 URLConnection 为例来介绍如何在 URLConnection 中使用代理服务器。
import java.io.IOException; import java.net.*; import java.util.Scanner; public class Demo { public static void main(String[] args) throws IOException { // 代理服务器的IP地址和端口 String ip = "118.190.158.17"; int port = 8080; // 定义需要访问的网站地址 String urlStr = "http://abc.com"; URL url = new URL(urlStr); // 创建一个代理服务器对象 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip, port)); // 使用指定的代理服务器打开连接 URLConnection conn = url.openConnection(proxy); // 设置超时时长 conn.setConnectTimeout(3000); // 通过代理服务器读取数据的Scanner Scanner scan = new Scanner(conn.getInputStream()); System.out.println("==================返回服务器响应的内容=================="); while (scan.hasNextLine()) { String line = scan.nextLine(); // 在控制台输出网页资源内容 System.out.println(line); } } }程序的运行结果如下:
============返回服务器响应的内容============= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Apache Tomcat/8.5.65</title> <link href="favicon.ico" rel="icon" type="image/x-icon" /> <link href="tomcat.css" rel="stylesheet" type="text/css" /> </head>程序中,第 16 行代码创建了一个 Proxy 对象,第 19 行代码就是用 Proxy 对象来打开 URLConnection 连接。接下来程序使用 URLConnection 读取了一份网络资源,此时的 URLConnection 并不是直接连接到 http://abc.com,而是通过代理服务器去访问该网站。
Java ProxySelector自动选择代理服务器
直接使用 Proxy 对象可以在打开 URLConnection 或 Socket 时指定代理服务器,但使用这种方式每次打开连接时都需要显式地设置代理服务器,比较麻烦。如果希望每次打开连接时总是具有默认的代理服务器,则可以借助于 ProxySelector 类来实现。ProxySelector 类代表一个代理选择器,它本身是一个抽象类,程序无法创建它的实例,开发者可以考虑继承 ProxySelector 类来实现自己的代理选择器。
实现 ProxySelector 类的步骤非常简单,程序只要定义一个继承 ProxySelector 类的类,并让该类实现如下两个抽象方法:
- List<Proxy> select(URI uri):根据业务需要返回代理服务器列表,如果该方法返回的集合中只包含一个 Proxy 对象,该 Proxy 对象将会作为默认的代理服务器。
- connectFailed(URI uri, SocketAddress sa, IOException ioe):连接代理服务器失败时回调该方法。
实现了自己的 ProxySelector 类之后,调用 ProxySelector 类的 setDefault(ProxySelector ps) 静态方法来注册该代理选择器即可。
接下来,通过案例来演示如何让自定义的 ProxySelector 类来自动选择代理服务器。
import java.io.IOException; import java.net.*; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Demo { public static void main(String[] args) throws IOException { // 设置默认代理选择器 ProxySelector.setDefault(new ProxySelector() { @Override public List<Proxy> select(URI uri) { List<Proxy> proxyList = new ArrayList<Proxy>(); // 代理服务器的IP地址和端口 String ip1 = "118.190.158.17"; int port1 = 8080; // 创建一个代理服务器对象 Proxy proxy1 = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip1, port1)); // 代理服务器的IP地址和端口 String ip2 = "118.190.158.17"; int port2 = 9090; // 创建一个代理服务器对象 Proxy proxy2 = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip2, port2)); proxyList.add(proxy2); proxyList.add(proxy1); return proxyList; } @Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { System.out.println("连接代理服务器失败!"); } }); // 定义需要访问的网站地址 String urlStr = "http://aaajy.net"; URL url = new URL(urlStr); // 不使用指定的代理服务器打开连接 URLConnection conn = url.openConnection(); // 设置超时时长 conn.setConnectTimeout(3000); // 通过代理服务器读取数据的Scanner Scanner scan = new Scanner(conn.getInputStream()); System.out.println("==================返回服务器响应的内容=================="); while (scan.hasNextLine()) { String line = scan.nextLine(); // 在控制台输出网页资源内容 System.out.println(line); } } }程序的运行结果如下:
连接代理服务器失败! ============返回服务器响应的内容============= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Apache Tomcat/8.5.65</title> <link href="favicon.ico" rel="icon" type="image/x-icon" /> <link href="tomcat.css" rel="stylesheet" type="text/css" /> </head>程序中,虽然没有使用代理服务器打开连接,但是代理服务器仍然起作用了,也就是说程序默认总会使用注册的代理服务器。
注意,代理服务器列表中保存的某个服务器无法连接的时候会出现“连接代理服务器失败!”的错误。