为什么运行Java应用程序时proxyHost / proxyPort不起作用?

时间:2011-07-21 17:25:31

标签: java fiddler

我有一个与一些REST服务对话的Java应用程序,我想查看使用Fiddler的HTTP流量。

Fiddler充当localhost:8888的代理,因此以下Java VM选项应该配置java以使用此代理:

-Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888

但是,如果我在运行我要调试的java应用程序时传递这些参数,我在Fiddler中看不到任何流量。

我编写了一个测试Java应用程序,它只使用HttpURLConnection执行HTTP GET。

如果我在从Eclipse调试时指定上述命令行参数,我可以在fiddler中查看此应用程序的HTTP流量。

http.proxyHost / Port可能无法用于所有Java HTTP操作的原因是什么?

4 个答案:

答案 0 :(得分:4)

您可以使用以下代码(HttpClient 4.x)告诉HttpClient遵守JDK系统参数。

public static final DefaultHttpClient HTTP = new DefaultHttpClient();
ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(HTTP.getConnectionManager().getSchemeRegistry(),
ProxySelector.getDefault());
HTTP.setRoutePlanner(routePlanner);

答案 1 :(得分:2)

对于4.3.6,我使用了

HttpHost proxy = new HttpHost(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort")), "http");//System.getProperty("http.proxyHost")
DefaultRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpClient = HttpClients.custom().setRoutePlanner(routePlanner).build();

答案 2 :(得分:2)

如上所述,你需要做这样的事情:

 CloseableHttpClient httpClient = HttpClients.custom()
   .setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault())

但这还不够。

在TL; DR方式中 - 您还需要所有这三个系统属性:

-Dhttp.proxyHost = localhost -Dhttp.proxyPort = 8888 -Dhttp.nonProxyHosts =

可以找到长答案here

Gerard Davison在上面的链接中提到:

  

开发基于服务器的应用程序时非常方便   使用“localhost”运行它们以保持之间的一致性   开发者机器。这通常是一个好主意,但有一个小的   这可能会导致问题。

     

考虑您是否在计算机上运行本地http代理   以捕获您的HTTP流量。 (甚至可能是咳嗽中的那个   我工作的JDeveloper)。然后你可能会遇到Java bug 6737819。   基本上默认情况下,JDK 1.6是硬编码的,不发送任何请求   localhost通过代理当然有点痛苦。幸运的是   解决方法放在你可以放入字符串“~localhost”的地方   你的nonProxyHosts条目转变了这个功能:

java -client -classpath classes 
-Dhttp.proxyHost=localhost 
-Dhttp.proxyPort=8099 -Dhttp.nonProxyHosts=~localhost 
-Dhttps.proxyHost=localhost 
-Dhttps.proxyPort=8099 client.Example 
     

现在转向JDK 1.7,这种解决方法不再适用;但是你   需要注意将nonProxyHosts定义为空字符串:

java -client -classpath classes 
-Dhttp.proxyHost=localhost 
-Dhttp.proxyPort=8099 
-Dhttp.nonProxyHosts= 
-Dhttps.proxyHost=localhost 
-Dhttps.proxyPort=8099 client.Example  
     

如果你定义除了空字符串之外的任何东西   DefaultProxySelector虽然要注意,因为它会在内部附加/   或者使用来自../jre/lib/net.properties的http.nonProxyHosts值。

     

只是一个轻微的并发症,在已发布的API中并不明显。

答案 3 :(得分:0)

使用Apache httpclient 4.3.6,您似乎应该使用SystemDefaultRoutePlanner。

SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(null);
CloseableHttpClient httpClient = HttpClientBuilder.create()
  .setRoutePlanner(routePlanner)
  .build();

这将从系统属性http.proxyHosthttp.proxyPort中获取代理设置,并在每次发送新的http请求时使用这些值的当前设置。