Java ApacheHttpComponents。获取连接请求的响应

Java ApacheHttpComponents。获取连接请求的响应,java,apache-httpclient-4.x,apache-httpcomponents,Java,Apache Httpclient 4.x,Apache Httpcomponents,我正在使用ApacheHtpComponents(版本-4.5.2),并试图通过代理服务器请求HTTPS页面 编辑: 我的主要问题是,我需要知道如何区分代理服务器的故障和请求的URI的故障(对于HTTP和HTTPS)。我有很多代理,它们不是100%可靠,所以在代理失败的情况下,我需要使用不同的代理服务器重试请求 例如(在HTTPS的情况下),NoHttpResponseException可以在两种情况下返回,即代理失败或目标URL失败。我怎样才能知道问题的根源?从哪里来的NoHttpRespon

我正在使用ApacheHtpComponents(版本-4.5.2),并试图通过代理服务器请求HTTPS页面

编辑:

我的主要问题是,我需要知道如何区分代理服务器的故障和请求的URI的故障(对于HTTP和HTTPS)。我有很多代理,它们不是100%可靠,所以在代理失败的情况下,我需要使用不同的代理服务器重试请求

例如(在HTTPS的情况下),
NoHttpResponseException
可以在两种情况下返回,即代理失败或目标URL失败。我怎样才能知道问题的根源?从哪里来的
NoHttpResponseException
?从目标URI的代理

我想我可以尝试读取
CONNECT
请求到代理服务器的响应,如果它是200,则表示代理是好的,下一个
NoHttpResponseException
来自目标URL。但如果我立即得到
NoHttpResponseException
(在代理返回连接的200状态码之前),这意味着代理本身存在问题,我需要使用不同的代理服务器重试请求。但我找不到任何文档如何访问代理服务器返回的
CONNECT
请求的响应


此外,有时我会得到
HttpHostConnectException
ConnectTimeoutException
。我将此异常视为代理(HTTP和HTTPS)的问题—这是正确的方法吗?或者,即使对于目标URL,也可能发生这2个异常

它不会很漂亮,但应该会有效果

HttpHost myproxy = new HttpHost("myproxy", 8080)
CloseableHttpClient client = HttpClientBuilder.create()
        .setProxy(myproxy)
        .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy() {

            @Override
            public boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) {

                if (myproxy.equals(authhost)) {
                    context.setAttribute("proxy.status", response.getStatusLine());
                }
                return super.isAuthenticationRequested(authhost, response, context);
            }
        })
        .build();

HttpClientContext context = HttpClientContext.create();
HttpGet get = new HttpGet("https://httpbin.org/");
try (CloseableHttpResponse response = client.execute(get, context)) {
    EntityUtils.consume(response.getEntity());
}
StatusLine proxyStatus = context.getAttribute("proxy.status", StatusLine.class);
System.out.println("Proxy said " + proxyStatus);

PS:
HttpHostConnectException
ConnectTimeoutException
异常只能在第一个跃点(即连接到代理时)引发。如果代理由于任何原因无法连接到目标服务器,则它可能会以5xx状态响应连接方法。

首先为什么要访问连接响应消息?@oleg oleg,我的问题的根源在于,我需要知道如何区分代理服务器的故障和请求的URI的故障。例如,在这两种情况下都可以返回
NoHttpResponseException
。因此,我想读取代理在连接请求之后返回的一些头(如果有一些头-这意味着代理很好并且目标URI有问题,如果代理服务器没有头-这意味着连接到代理时发生了
NoHttpResponseException
)@oleg如果您对如何区分代理服务器故障和请求的URI故障(特别是与
NoHttpResponseException
)有任何其他建议,请帮助我。感谢代理服务器的故障,您的意思是代理服务器无法处理任何请求或仅处理特定的请求。如果它是第一个,那么您可以在代理服务器中托管一个简单页面,并在出现任何故障时尝试检索该页面,如果无法检索该简单页面,那么代理将关闭。除此之外,您可以尝试使用相同的配置托管多个代理服务器,如果两个代理服务器都出现故障,则很可能是远程服务器(而不是代理服务器)出现故障。我对我的问题进行了一些编辑,现在应该更容易理解我想要的内容。谢谢,这应该会有所帮助!您能回答我问题的最后一段吗(关于
HttpHostConnectException
ConnectTimeoutException
)?我需要知道此异常是否只能在代理服务器上发生,还是在这两种情况下都会发生。我尝试了此代码,但
HttpResponse
对象包含来自请求的URI的信息,而不是来自代理对
CONNECT
请求的答复的信息。也就是说,它与直接使用
response.getStatusLine()
相同。在日志中,我看到代理返回此状态行:
HTTP/1.1200已建立连接
,但
context.getAttribute(“proxy.status”,StatusLine.class)
返回
HTTP/1.1200 OK
-也就是说,它是来自远程服务器的响应,而不是来自代理。为了证明这一点,我甚至尝试从远程服务器而不是代理服务器获取头文件,而不是状态行。根据日志,我知道这个方法被调用了两次。第一次来自代理的响应,第二次来自远程服务器的实际响应。所以
“proxy.status”
在第二次调用中被覆盖。这很容易修复,不是吗?我用最简单的解决方案更新了代码。
authhost
始终是代理服务器,但响应可以来自目标URL或代理。我像这样使用了guard`if(context.getAttribute(“proxy.response”)==null)`{//set proxy response}`