常用的HTTP客户端和代理

Posted

技术标签:

【中文标题】常用的HTTP客户端和代理【英文标题】:Common HTTPclient and proxy 【发布时间】:2012-03-21 19:51:34 【问题描述】:

我正在使用 apache 的通用 httpclient 库。是否可以通过代理发出 HTTP 请求?更具体地说,我需要对多线程 POST 请求使用代理列表(现在我正在使用单线程 GET 请求进行测试)。

我尝试使用:

        httpclient.getHostConfiguration().setProxy("67.177.104.230", 58720);

我收到该代码的错误:

21.03.2012. 20:49:17 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused: connect
21.03.2012. 20:49:17 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
21.03.2012. 20:49:19 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused: connect
21.03.2012. 20:49:19 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
21.03.2012. 20:49:21 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused: connect
21.03.2012. 20:49:21 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
org.apache.commons.httpclient.ProtocolException: The server xxxxx failed to respond with a valid HTTP response
    at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1846)
    at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1590)
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:995)
    at org.apache.commons.httpclient.ConnectMethod.execute(ConnectMethod.java:144)
    at org.apache.commons.httpclient.HttpMethodDirector.executeConnect(HttpMethodDirector.java:495)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:390)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
    at test.main(test.java:42)

当我删除该行时,一切都按预期运行。

【问题讨论】:

确实有可能。在您的例外情况下,哪个主机是经过编辑的xxxxx?您的代理或目的地?为什么你有这么多连接被拒绝?您的代理实际上是否正常工作? xxxxx 是我发送请求的服务器,而不是代理服务器。代理应该可以工作。我正在使用 socks5 类型的代理。 您配置了 HTTP 代理,而不是 SOCKS 代理。 HttpClient 3 不支持 SOCKS。您可以使用系统属性“socksProxyHost”和“socksProxyPort”。或者 HttpComponents HttpClient 4 可能支持 SOCKS 代理。 即使我使用 http/https 代理,我也会遇到很多错误。真的不知道怎么回事。我尝试了 HttpComponents 和 Commons HttpClient 新的错误是什么? 【参考方案1】:

对于 httpclient 4.1.x 你可以这样设置代理(取自this example):

    HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");

    DefaultHttpClient httpclient = new DefaultHttpClient();
    try 
        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        HttpHost target = new HttpHost("issues.apache.org", 443, "https");
        HttpGet req = new HttpGet("/");

        System.out.println("executing request to " + target + " via " + proxy);
        HttpResponse rsp = httpclient.execute(target, req);
        ...
     finally 
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
    

【讨论】:

我没有使用新的HTTP组件,我使用的是commons httpclient。也许我应该转移...... 我参加聚会有点晚了,但这对我的内部开发设置很有魅力。非常感谢并投赞成票。【参考方案2】:

这是使用最新版本 HTTPClient (4.3.4) 的方法

    CloseableHttpClient httpclient = HttpClients.createDefault();
    try 
        HttpHost target = new HttpHost("localhost", 443, "https");
        HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");

        RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .build();
        HttpGet request = new HttpGet("/");
        request.setConfig(config);

        System.out.println("Executing request " + request.getRequestLine() + " to " + target + " via " + proxy);

        CloseableHttpResponse response = httpclient.execute(target, request);
        try 
            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            EntityUtils.consume(response.getEntity());
         finally 
            response.close();
        
     finally 
        httpclient.close();
    

【讨论】:

嗨,在哪里为代理用户/通行证设置凭据。抱歉,不确定。 你可以看看这里***.com/questions/19252946/… 如何使用'CloseableHttpClient httpclient = HttpClients.createDefault();'从tomcat?我有一个 servlet,它调用静态函数,假设将 http 请求发送到另一台服务器【参考方案3】:

从 Apache HTTPComponents 4.3.x 开始,HttpClientBuilder 类从系统属性 http.proxyHosthttp.proxyPort 设置代理默认值,否则您可以使用 setProxy 方法覆盖它们。

【讨论】:

【参考方案4】:

虽然这个问题很老了,但我看到仍然没有确切的答案。我将尝试在这里回答这个问题。

我相信这里的简短问题是如何为 Apache commons HttpClient (org.apache.commons.httpclient.HttpClient) 设置代理设置。

下面的代码 sn-p 应该可以工作:

HttpClient client = new HttpClient();
HostConfiguration hostConfiguration = client.getHostConfiguration();
hostConfiguration.setProxy("localhost", 8080);
client.setHostConfiguration(hostConfiguration);

【讨论】:

【参考方案5】:

以下是我如何使用 Santosh Singh(我给了 +1)的答案为旧的 (

HttpClient httpclient = new HttpClient();
if (System.getProperty("http.proxyHost") != null) 
  try 
    HostConfiguration hostConfiguration = httpclient.getHostConfiguration();
    hostConfiguration.setProxy(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort")));
    httpclient.setHostConfiguration(hostConfiguration);
    this.getLogger().warn("USING PROXY: "+httpclient.getHostConfiguration().getProxyHost());
   catch (Exception e) 
    throw new ProcessingException("Cannot set proxy!", e);
  

【讨论】:

【参考方案6】:

HttpClient 第 4 版也有类似的问题。

由于 SOCKS 代理错误,我无法连接到服务器,我使用以下配置修复了它:

client.getParams().setParameter("socksProxyHost",proxyHost);
client.getParams().setParameter("socksProxyPort",proxyPort);

【讨论】:

经过数小时的搜索后,这个答案帮助了我。确实感谢一万亿!【参考方案7】:

如果您的软件使用ProxySelector(例如,用于使用 PAC 脚本而不是静态主机/端口)并且您的 HTTPComponents 是 4.3 或更高版本,那么您可以将您的 ProxySelector 用于您的 HttpClient,例如这个:

ProxySelector myProxySelector = ...;
HttpClient myHttpClient = HttpClientBuilder.create().setRoutePlanner(new SystemDefaultRoutePlanner(myProxySelector))).build();

然后照常执行您的请求:

HttpGet myRequest = new HttpGet("/");
myHttpClient.execute(myRequest);

【讨论】:

以上是关于常用的HTTP客户端和代理的主要内容,如果未能解决你的问题,请参考以下文章

squid 的一些常用操作,以及反向代理测试

Web 结构组件

Fiddler的原理和基本介绍

fiddler之使用教程

Fiddler的学习之路

移动端数据爬取