【问题标题】:Why don't proxyHost/proxyPort work when running my Java application?为什么运行我的 Java 应用程序时 proxyHost/proxyPort 不工作?
【发布时间】:2011-07-21 17:25:31
【问题描述】:

我有一个与一些 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 操作的原因是什么?

【问题讨论】:

  • 你运行的java版本是什么?运行 java -version (以防万一)。您是否有可能在您的机器上安装了旧的 JRE?自 java 1.5 起支持这些属性
  • 命令行报告的版本是1.6.0_26。在 Eclipse 中调试我的小型测试应用程序时,这些选项确实有效。
  • (1) 检查您在 Eclipse 中使用的是哪个 JRE。它与从命令行运行时使用的相同吗? (2) 您是否尝试从命令行运行小测试(可在 eclipse 中运行)?如果不先试试。如果在测试开始时打印系统属性不起作用。那么您能否发布您正在使用的完整命令行?
  • 好建议。我发现我要测试的应用程序正在使用 Apache HTTP 客户端库,这些库显然没有与这些代理配置命令行设置挂钩:cephas.net/blog/2007/11/14/…
  • 你还需要一个空的 nonProxyHosts : -Dhttp.nonProxyHosts=

标签: java fiddler


【解决方案1】:

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

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

【讨论】:

  • 所有这些都已在 4.3 中被弃用。有谁知道在 4.3.6+ 中执行此操作的最佳方法?
【解决方案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】:

    对于 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();
    

    【讨论】:

    • 这会起作用,但如果http.proxyHosthttp.proxyPort 的值在程序运行时发生变化,该方法将不会注意到变化。您可以将SystemDefaultRoutePlanner 用于自动适应的版本。
    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      相关资源
      最近更新 更多