use*_*788 3 java apache apache-httpclient-4.x
我读过这个:
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());
}
Run Code Online (Sandbox Code Playgroud)
以及唯一的 Maven 依赖项:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
由于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());
}
Run Code Online (Sandbox Code Playgroud)
此外,一个站点可以有多个可以解析的 IP,上层解决方案将只选择它连接的第一个。如果您想要其他 IP,您必须自己解决它们:
SystemDefaultDnsResolver r = new SystemDefaultDnsResolver();
InetAddress[] resolve = r.resolve("google.com");
Run Code Online (Sandbox Code Playgroud)
这可能会导致额外的 dns 检查和糟糕的性能。我读到的是设置nscd服务来缓存 dns 检查并加速请求。
| 归档时间: |
|
| 查看次数: |
3220 次 |
| 最近记录: |