我读过这个:
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(上下文)在抽象中创建了简单的javaSocket,我试图覆盖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检查并加快请求。