如何使HttpURLConnection使用代理?


136

如果我这样做

conn = new URL(urlString).openConnection();
System.out.println("Proxy? " + conn.usingProxy());

它打印

Proxy? false

问题是,我在代理后面。JVM在Windows的哪里获取代理信息?我该如何设置?我所有其他应用似乎都对我的代理完全满意。

Answers:


336

从Java 1.5开始,您还可以将java.net.Proxy实例传递给该openConnection(proxy)方法:

//Proxy instance, proxy ip = 10.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
conn = new URL(urlString).openConnection(proxy);

如果您的代理要求验证,它将给您响应407。

在这种情况下,您需要以下代码:

    Authenticator authenticator = new Authenticator() {

        public PasswordAuthentication getPasswordAuthentication() {
            return (new PasswordAuthentication("user",
                    "password".toCharArray()));
        }
    };
    Authenticator.setDefault(authenticator);

7
我们可以通过它提供代理用户名和代理密码吗?
Xolve

15
如果您为不同的代理使用不同的用户名/密码对,该怎么办?调用静态方法来设置默认的Authenticator并不理想,这并不比设置sys属性方法好多少
。– javaPhobic,2015年

2
Authenticator.default是静态(即全局)变量,因此只有一次。但是请注意,上面的Authenticator只是一个最小的示例。一次只能处理一个密码。以Google为例,可以使用不同的密码处理多个主机。
Stroboskop,

3
由于8u11在默认情况下无法使用基本身份验证进行操作, 因此必须将oracle.com/technetwork/java/javase/8u111-relnotes-3124969.html jdk.http.auth.tunneling.disabledSchemes系统属性设置为空
白色

3
如果您有域名。请执行以下操作:new PasswordAuthentication("domainName\\user", "password".toCharArray());
开发人员MariusŽilėnas17年

34

从互联网上很容易回答。设置系统属性http.proxyHosthttp.proxyPort。您可以使用System.setProperty(),也可以使用-D语法从命令行执行此操作。


19

通过两个系统属性支持代理:http.proxyHost和http.proxyPort。它们必须分别设置为代理服务器和端口。以下基本示例对此进行了说明:

String url = "http://www.google.com/",
       proxy = "proxy.mydomain.com",
       port = "8080";
URL server = new URL(url);
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port);
HttpURLConnection connection = (HttpURLConnection)server.openConnection();
connection.connect();
InputStream in = connection.getInputStream();
readResponse(in);

@Pascal您是否知道与Apache相比,使用最新Java方法的主要区别是commons-httpclient什么?由于Java支持代理和身份验证(如您在此处提到的stackoverflow.com/questions/1626549/…),对于简单的情况(例如从公共HTTP服务器检索一个文件),没有理由使用Apache库。您有什么建议?
dma_k 2010年

@dma_k我同意您的看法,对于您所描述的简单用例,我不会使用第三方库。
Pascal Thivent

您知道如何支持nonProxyHosts吗?我看到我的设备支持它,但不知道如何使我的应用程序处理它。
RiRomain '16

但是!systemProperties不使用变量connection
parsecer

12

您也可以设定

-Djava.net.useSystemProxies=true

在Windows和Linux上,这将使用系统设置,因此您无需重复自己(DRY)

http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies


6
这仅适用于手动代理服务器配置。通过脚本配置的自动代理配置和代理(尚未)尚未传播到“ useSystemProxies”。
轮胎

1
这在设置proxyHost和proxyPort不起作用时对我有用。谢谢!
nrobey

同样,这个从后面我公司代理时,曾呼吁System.setPropertyhttps.proxyHosthttps.proxyPort出于某种原因未切割的芥末。
帕维尔·科马罗夫

10

在openConnection之前设置以下内容,

System.setProperty("http.proxyHost", "host");
System.setProperty("http.proxyPort", "port_number");

如果代理要求验证,

System.setProperty("http.proxyUser", "user");
System.setProperty("http.proxyPassword", "password");

7
我实际上认为不再支持“ http.proxyUser”和“ http.proxyPassword”。有关更多详细信息,请参见stackoverflow.com/questions/120797/…
p3t0r

5

对于Java 1.8及更高版本,您必须设置-Djdk.http.auth.tunneling.disabledSchemes=为使用https进行“基本授权”代理。


1
有关此内容的背景信息,请
参见

2

如果您知道您的代理主机和port =),则已批准的答案将起作用。但是,如果您正在寻找代理主机和端口,则以下步骤应该会有所帮助

如果给出了自动配置的代理:则

1>打开IE(或任何浏览器)

2>通过IE->工具-> Internet选项->连接-> LAN设置->获取地址并输入url,例如:http ://autocache.abc.com/,从浏览器获取URL地址, 并输入一个文件将以.pac格式下载,保存到桌面

3>在文本键盘中打开.pac文件,识别PROXY:

在您的编辑器中,它将类似于:

返回“ PROXY web-proxy.ind.abc.com:8080; PROXY proxy.sgp.abc.com:8080”;

在5分钟内无法Maven中获得赞誉

一旦有了主机和端口,就可以进入其中

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("web-proxy.ind.abc.com", 8080));
        URLConnection connection = new URL(url).openConnection(proxy);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.