HttpClient获取访问域名的真实ip,HttpClient请求获取目标IP地址

soゝso 2019-04-11 22:09:24 522

  HttpClient   请求一个域名,想知道这个域名的IP地址,以为我们现在一般都是  CDN  负载的,也就是会有多个IP地址,所以有这个需求。

网上找了一下,没有什么好办法。

看了下网上的教材,要从 Socket.getInetAddress().getHostAddress() 获取   IP   地址,看了下源码 HttpConnectionManager 中的成员变量 HttpConnection 的 getSocket() 方法是 protected 的。

/**
 * Returns the connection socket.
 *
 * @return the socket.
 * 
 * @since 3.0
 */
protected Socket getSocket() {
    return this.socket;
}

所以直接使用不了,我的思路是。

一、获取真实IP、Head信息、请求状态

1. 创建一个 SHttpConnection extends HttpConnection ,根据提示实现需要实现的方法。

    再创建一个获取 Socket 的方法。

/**
 * 从父类获取socket对象
 * @return
 */
public Socket getNowSocket() {
    return getSocket();
}

2. 创建 SHttpConnectionManager implements HttpConnectionManager ,直接复制 HttpConnectionManager 里的方法,然后修改 HttpConnection 成自己的 SHttpConnection 对象。

3. 开始请求,我的需求只是获取目标的   HTTP   状态,另外还有 IP 地址,以及请求头信息 。

/**
 * 获取一个连接的状态,IP地址,head信息
 * @param url
 * @return
 */
public static Map<String,Object> getStatus(String url){
    HttpClient client = new HttpClient();
    try {
        Map<String,Object> result = new TreeMap<>();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(1500);
        client.getHttpConnectionManager().getParams().setSoTimeout(1500);

        //浏览器方式模拟
        client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"UTF-8");
        client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
        GetMethod method = new GetMethod(url);

        //必要的头信息
        method.setRequestHeader("Accept", "*/*");
        method.setRequestHeader("Accept-Encoding", "gzip, deflate");
        method.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
        method.setRequestHeader("Connection","close");
        method.setRequestHeader("Host", url);
        method.setRequestHeader("Referer", "https://www.baidu.com/s?wd=sojson");
        method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");



        //设置一个 HttpConnectionManager,我们自己实现 HttpConnectionManager
        client.setHttpConnectionManager(new SHttpConnectionManager());

        //执行
        int status = client.executeMethod(method);

        //获取 Header
        Header[] headers = method.getResponseHeaders();

        //头信息转换成Map
        Map<String,Object> map = Arrays.stream(headers).collect(Collectors.toMap(Header::getName,Header::getValue));

        //获取 HttpConnectionManager
        SHttpConnectionManager manager = (SHttpConnectionManager)client.getHttpConnectionManager();

        Socket hostAddress = manager.getNowSocket();

        String ip = hostAddress.getInetAddress().getHostAddress();
        result.put("ip",ip);
        result.put("status",status);
        result.put("header",map);

        return result;
    } catch (IOException e) {
        return null;
    }
}

二、SHttpConnection 和 SHttpConnectionManager 的源码

1.SHttpConnection 源码

public class SHttpConnection extends HttpConnection{

    public SHttpConnection(String host, int port) {
        super(host, port);
    }

    /**
     * 从父类获取socket对象
     * @return
     */
    public Socket getNowSocket() {
        return getSocket();
    }
    public SHttpConnection(String host, int port, Protocol protocol) {
        super(host, port, protocol);
    }

    public SHttpConnection(String host, String virtualHost, int port, Protocol protocol) {
        super(host, virtualHost, port, protocol);
    }

    public SHttpConnection(String proxyHost, int proxyPort, String host, int port) {
        super(proxyHost, proxyPort, host, port);
    }

    public SHttpConnection(HostConfiguration hostConfiguration) {
        super(hostConfiguration);
    }

    public SHttpConnection(String proxyHost, int proxyPort, String host, String virtualHost, int port, Protocol protocol) {
        super(proxyHost, proxyPort, host, virtualHost, port, protocol);
    }

    public SHttpConnection(String proxyHost, int proxyPort, String host, int port, Protocol protocol) {
        super(proxyHost, proxyPort, host, port, protocol);
    }
}

2.SHttpConnectionManager 源码

public class SHttpConnectionManager implements HttpConnectionManager {
        private static final Log LOG = LogFactory.getLog(SimpleHttpConnectionManager.class);

        private static final String MISUSE_MESSAGE = "SimpleHttpConnectionManager being used incorrectly.  Be sure that"
                        + " HttpMethod.releaseConnection() is always called and that only one thread"
                        + " and/or method is using this connection manager at a time.";


        static void finishLastResponse(HttpConnection conn) {
            InputStream lastResponse = conn.getLastResponseInputStream();
            if (lastResponse != null) {
                conn.setLastResponseInputStream(null);
                try {
                    lastResponse.close();
                } catch (IOException ioe) {
                    conn.close();
                }
            }
        }

        protected SHttpConnection httpConnection;

        private HttpConnectionManagerParams params = new HttpConnectionManagerParams();

        private long idleStartTime = Long.MAX_VALUE;

        private volatile boolean inUse = false;

        private boolean alwaysClose = false;




        public SHttpConnectionManager() {
            super();
        }


        public HttpConnection getConnection(HostConfiguration hostConfiguration) {
            return getConnection(hostConfiguration, 0);
        }
        public Socket getNowSocket() {
            return this.httpConnection.getNowSocket();
        }

        public boolean isConnectionStaleCheckingEnabled() {
            return this.params.isStaleCheckingEnabled();
        }


        public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
            this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
        }

        public HttpConnection getConnectionWithTimeout(
                HostConfiguration hostConfiguration, long timeout) {

            if (httpConnection == null) {
                httpConnection = new SHttpConnection(hostConfiguration);
                httpConnection.setHttpConnectionManager(this);
                httpConnection.getParams().setDefaults(this.params);
            } else {

                if (!hostConfiguration.hostEquals(httpConnection)
                        || !hostConfiguration.proxyEquals(httpConnection)) {

                    if (httpConnection.isOpen()) {
                        httpConnection.close();
                    }

                    httpConnection.setHost(hostConfiguration.getHost());
                    httpConnection.setPort(hostConfiguration.getPort());
                    httpConnection.setProtocol(hostConfiguration.getProtocol());
                    httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());

                    httpConnection.setProxyHost(hostConfiguration.getProxyHost());
                    httpConnection.setProxyPort(hostConfiguration.getProxyPort());
                } else {
                    finishLastResponse(httpConnection);
                }
            }

            // remove the connection from the timeout handler
            idleStartTime = Long.MAX_VALUE;

            if (inUse) LOG.warn(MISUSE_MESSAGE);
            inUse = true;

            return httpConnection;
        }


        public HttpConnection getConnection(
                HostConfiguration hostConfiguration, long timeout) {
            return getConnectionWithTimeout(hostConfiguration, timeout);
        }

        public void releaseConnection(HttpConnection conn) {
            if (conn != httpConnection) {
                throw new IllegalStateException("Unexpected release of an unknown connection.");
            }
            if (this.alwaysClose) {
                httpConnection.close();
            } else {
                finishLastResponse(httpConnection);
            }

            inUse = false;
            idleStartTime = System.currentTimeMillis();
        }


        public HttpConnectionManagerParams getParams() {
            return this.params;
        }


        public void setParams(final HttpConnectionManagerParams params) {
            if (params == null) {
                throw new IllegalArgumentException("Parameters may not be null");
            }
            this.params = params;
        }


        public void closeIdleConnections(long idleTimeout) {
            long maxIdleTime = System.currentTimeMillis() - idleTimeout;
            if (idleStartTime <= maxIdleTime) {
                httpConnection.close();
            }
        }


        public void shutdown() {
            httpConnection.close();
        }
    }

3.   Maven  依赖

<dependency>
	<groupId>commons-httpclient</groupId>
	<artifactId>commons-httpclient</artifactId>
	<version>3.1</version>
</dependency>


版权所属:SO JSON在线解析

原文地址:https://www.sojson.com/blog/319.html

转载时必须以链接形式注明原始出处及本声明。

本文主题:

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

相关文章
Java获取域名,Java从URL地址获取域名,Java从Request 获取域名
HttpClient 获取详细的头信息
Java 正则获取一级域名
Java获取重定向后的真实URL地址
JSON格式讲解,JSON获取对象,JSONObject和JSONArray的操作
Java 获取HTPP 301 / 302 重定向后的Url地址,301和302对SEO的影响
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报
IE、Firefox对同一域名访问并发限制,及解决优化方案
Java 获取时间戳的方法大全,以及速度比较
Java 实现多个二级域名访问同一个Tomcat(系统)。
最新文章
Linux Centos 使用 Redis service 启动,Redis service 脚本编写 36
恭喜SOJSON获得阿里云618“上云接力赛”第一名,获得代金券6.18万 192
Springboot 集成Freemarker 自定义标签解决方案 504
七牛云到底有多垃圾?用七牛云需要知道的事,不然不小心就一套房没了 28193
JavaScript怎么识别360浏览器?JS识别360急速模式方案,360流氓浏览器 1090
关于本站所有JavaScript 加密、混淆、解密、美化等安全说明 1810
Jsoup 提交参数乱码,解决思路,解决过程及解决方案 839
生成新浪短网址、百度短网址,t.cn / dwz.cn 的生成方式,短链还原 825
ICP怎么操作取消备案,企业、个人怎么自己申请取消备案? 631
Javascript 加密/压缩后运行不了,JavaScript报错排查讲解 575
最热文章
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报 179883
Elasticsearch教程(四) elasticsearch head 插件安装和使用 140457
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 137927
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 88867
Elasticsearch教程(六) elasticsearch Client创建 82547
Elasticsearch教程(一),全程直播(小白级别) 78852
Elasticsearch教程(二),IK分词器安装 77717
Elasticsearch教程(八) elasticsearch delete 删除数据(Java) 77175
Elasticsearch教程(五) elasticsearch Mapping的创建 70725
免费天气API,天气JSON API,不限次数获取十五天的天气预报 60602

骚码加入我们 / 千人QQ群:259217951

入群需要5元,如果没有QQ钱包,可以先Alipay、微信,赞助然后加群主拉进。

二维码生成 来自 >> 二维码生成器

支付扫码

所有赞助/开支都讲公开明细,用于网站维护:赞助名单查看

正在加载... ...