java - Apache HttpClient 4.3.3 如何找到请求站点的目标IP

标签 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());

    }

以及唯一的 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/

相关文章:

java - 正则表达式中的标点符号

apache - 使用 $10、$11、$12 等重写规则

php - 在本地 xampp/apache 服务器上设置 SSL

java - 尝试通过 https 和基本身份验证获取 http 响应 - 获取 "Unauthorized"

Java 和 HttpsUrlConnection 忽略 ssl 证书

java - 如何在ormlite中保存带有 'foreign object'的对象

java - 我可以安装 32 位 JVM 和 64 位 JVM 吗?

java - 如何使用indexOf打印出indexOf范围?

java - 配置 jboss dashbuilder 以使用 apache httpd 身份验证

java - httpclient 可以使用当前登录用户自动创建授权 header 作为 java URLConnection 吗?