【问题标题】:Apache HttpClient 4.3.3 how to find target IP of the requested siteApache HttpClient 4.3.3 如何找到请求站点的目标IP
【发布时间】:2014-04-24 23:08:28
【问题描述】:

我读过这篇:

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 解析。

还有一个代码sn-p,它近似于链接中写入的内容,并且两行输出均为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>       

【问题讨论】:

  • 那么你的目标是什么?你尝试了什么?你是怎么失败的?
  • 抱歉描述模糊。希望这不那么晦涩。

标签: java apache apache-httpclient-4.x


【解决方案1】:

由于 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 检查并加速请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2015-03-18
    • 2019-10-12
    • 1970-01-01
    相关资源
    最近更新 更多