Apache HttpClient 4.3.3如何查找请求站点的目标IP



我读过这个:

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检查并加快请求。

最新更新