我读过这个:
http://httpcomponents.10934.n7.nabble.com/get-InetAddress-for-the-HTTP-TARGET-HOST-td18332.html
而且我不知道如何使用最新的 Apache HttpClient 4.3.3 执行相同的操作。 我想做的是获取请求站点的IP。我知道这对于最小的 httpclient 是不可能的,但究竟应该如何使用呢?
由于最小的 httpclient 有 PoolingHttpClientConnectionManager(HttpClientConnectionManager) 作为参数但没有 ClientConnectionManager 我不知道要覆盖哪些方法以及要设置哪些属性。 上面的示例可以直接访问套接字,而新示例则不是这样。
所以问题是如何使用新的 (4.3.3) API 做到这一点。 以及保持已解析的 IP 不被重定向是正确的,例如,避免 第二个 DNS 解析。
还有一个代码片段,它近似于链接中所写的内容,并且两行输出都是 NULL:
public static void main(String[] args) throws ClientProtocolException,
IOException {
String s = "http://google.com";
PoolingHttpClientConnectionManager m = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory() {
@Override
public Socket createSocket(HttpContext context)
throws IOException {
Socket s = super.createSocket(context);
context.setAttribute("sock-address",
s.getRemoteSocketAddress());
return s;
}
}).build(), new SystemDefaultDnsResolver());
CloseableHttpClient minimal = HttpClients.createMinimal(m);
HttpGet get = new HttpGet(s);
HttpClientContext context = HttpClientContext.create();
CloseableHttpResponse response = minimal.execute(get, context);
InetSocketAddress addr = (InetSocketAddress) context
.getAttribute("sock-address");
HttpHost target = (HttpHost) context
.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
System.out.println(addr);
System.out.println(target.getAddress());
}
以及唯一的 Maven 依赖项:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
最佳答案
由于 Socket s = super.createSocket(context); 在抽象中创建了简单的 java Socket,我尝试覆盖 connectSocket 方法,这次它起作用了。这是工作示例:
public static void main(String[] args) throws ClientProtocolException,
IOException {
String s = "http://google.com";
PoolingHttpClientConnectionManager m = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory() {
@Override
public Socket connectSocket(int connectTimeout,
Socket socket, HttpHost host,
InetSocketAddress remoteAddress,
InetSocketAddress localAddress,
HttpContext context) throws IOException {
context.setAttribute("sock-address",
remoteAddress);
return super.connectSocket(connectTimeout,
socket, host, remoteAddress,
localAddress, context);
}
}).build(), new SystemDefaultDnsResolver());
CloseableHttpClient minimal = HttpClients.custom()
.setConnectionManager(m).build();
HttpGet get = new HttpGet(s);
HttpClientContext context = HttpClientContext.create();
CloseableHttpResponse response = minimal.execute(get, context);
InetSocketAddress addr = (InetSocketAddress) context
.getAttribute("sock-address");
System.out.println(addr.getAddress().getHostAddress());
}
此外,一个站点可能有多个 IP 可以解析到,而上层解决方案将只选择它连接的第一个。如果你想要其他 IP,你必须自己解决它们:
SystemDefaultDnsResolver r = new SystemDefaultDnsResolver();
InetAddress[] resolve = r.resolve("google.com");
这可能会导致额外的 DNS 检查和糟糕的性能。我读到的是设置 nscd 缓存 dns 检查并加速请求的服务。
关于java - Apache HttpClient 4.3.3 如何找到请求站点的目标IP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23281462/