基于apache httpclient的http访问工具

本贴最后更新于 3042 天前,其中的信息可能已经天翻地覆

代码是对apache httpclient的简单封装,支持用户登录,调用方式如下

import org.junit.Test;

/**
 * @author niuhaipeng
 *
 * @date 2015年12月24日
 */
public class HttpClientTest {

    @Test
    public void testGet2String() {
        SimpleHttpClient client = new SimpleHttpClient();
        String url = "http://niuhp.com";
        while (true) {
            String content = client.doGet2String(url);
            System.out.println(content);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

实现代码

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.niuhp.toolbox.logadapter.LogX;
import com.niuhp.toolbox.util.IoUtil;

/**
 * @author niuhaipeng
 *
 * @date 2015年12月17日
 */
public class SimpleHttpClient {

    private HttpClient httpClient;
    private Object lockObj = new Object();

    private int connectionRequestTimeout = 10000;
    private int connectTimeout = 10000;
    private int defaultMaxPerRoute = 20;
    private int maxTotal = 100;
    /**
     * 请求自动关闭时间,防止调用者长期持有请求
     */
    private long autoCloseTimeout = 3000;
    private final ExecutorService executorService = Executors.newFixedThreadPool(50);

    private void checkInit(boolean https) {
        if (httpClient != null) {
            return;
        }
        synchronized (lockObj) {
            if (httpClient != null) {
                return;
            }
            Builder builder = RequestConfig.custom();
            builder.setCookieSpec(CookieSpecs.STANDARD_STRICT);
            builder.setConnectionRequestTimeout(connectionRequestTimeout);
            builder.setConnectTimeout(connectTimeout);
            if (https) {
                builder.setExpectContinueEnabled(true);
                Collection<String> targetPreferredAuthSchemes = Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST);
                builder.setTargetPreferredAuthSchemes(targetPreferredAuthSchemes);
                Collection<String> proxyPreferredAuthSchemes = Arrays.asList(AuthSchemes.BASIC);
                builder.setProxyPreferredAuthSchemes(proxyPreferredAuthSchemes);
            }
            RequestConfig config = builder.build();

            HttpClientBuilder httpClientBuilder = HttpClients.custom();
            httpClientBuilder.setDefaultRequestConfig(config);
            if (https) {
                RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
                registryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE);
                TrustManager trustManager = new CustomizedX509TrustManager();

                try {
                    SSLContext context = SSLContext.getInstance("TLS");
                    context.init(null, new TrustManager[] { trustManager }, null);
                    ConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(context,
                            NoopHostnameVerifier.INSTANCE);
                    registryBuilder.register("https", connectionSocketFactory);
                } catch (Exception e) {
                    LogX.getLogX(getClass()).error("register connectionSocketFactory error", e);
                }
                Registry<ConnectionSocketFactory> registry = registryBuilder.build();
                PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
                connManager.setMaxTotal(maxTotal);
                connManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
                httpClientBuilder.setConnectionManager(connManager);
            }
            httpClient = httpClientBuilder.build();
        }
    }

    public String doGet2String(String url) {
        return doGet2String(url, null);
    }

    public String doGet2String(String url, Map<String, String> paraMap) {
        HttpResponse reponse = doGet(url, paraMap);
        return getContent(reponse);
    }

    public HttpResponse doGet(String url, Map<String, String> paraMap) {
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(url);
        if (paraMap != null && !paraMap.isEmpty()) {
            urlBuilder.append("?");
            Set<String> keys = paraMap.keySet();
            Iterator<String> it = keys.iterator();
            String key = it.next();
            urlBuilder.append(key).append("=").append(paraMap.get(key));
            while (it.hasNext()) {
                key = it.next();
                urlBuilder.append("&").append(key).append("=").append(paraMap.get(key));
            }
        }
        return doGet(urlBuilder.toString());
    }

    public HttpResponse doGet(String url) {
        boolean https = url != null && url.startsWith("https");
        checkInit(https);
        HttpGet get = new HttpGet(url);
        return doRequest(httpClient, get);
    }

    public String doPost2String(String url) {
        return doPost2String(url, null);
    }

    public String doPost2String(String url, Map<String, String> paraMap) {
        HttpResponse response = doPost(url, paraMap);
        return getContent(response);
    }

    public HttpResponse doPost(String url) {
        return doPost(url, null);
    }

    public HttpResponse doPost(String url, Map<String, String> paraMap) {
        boolean https = url != null && url.startsWith("https");
        checkInit(https);
        HttpPost post = new HttpPost(url);
        List<NameValuePair> values = toValues(paraMap);
        if (values != null && !values.isEmpty()) {
            HttpEntity entity = new UrlEncodedFormEntity(values, Consts.UTF_8);
            post.setEntity(entity);
        }
        return doRequest(httpClient, post);
    }

    private void autoClose(HttpUriRequest request, HttpResponse reponse) {
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(autoCloseTimeout);
                } catch (InterruptedException e) {
                    LogX.getLogX(getClass()).error("sleep error", e);
                }
                if (request instanceof HttpRequestBase) {
                    HttpRequestBase httpRequestBase = (HttpRequestBase) request;
                    httpRequestBase.releaseConnection();
                }
                IoUtil.closeHttpResponse(reponse);
                LogX.getLogX(getClass()).info(String.format("autoClose request[%s] and reponse[%s]", request, reponse));
            }
        };

        executorService.execute(runnable);
    }

    private HttpResponse doRequest(HttpClient httpClient, HttpUriRequest httpRequest) {
        synchronized (httpClient) {
            try {
                HttpResponse response = httpClient.execute(httpRequest);
                autoClose(httpRequest, response);
                return response;
            } catch (Exception e) {
                LogX.getLogX(getClass()).error("execute error", e);
            }
        }
        return null;
    }

    public void closeHttpClient() {
        IoUtil.closeHttpClient(httpClient);
    }

    private static List<NameValuePair> toValues(Map<String, String> paraMap) {
        if (paraMap == null) {
            return null;
        }
        List<NameValuePair> values = new ArrayList<NameValuePair>(paraMap.size());
        Set<String> keys = paraMap.keySet();
        for (String key : keys) {
            NameValuePair pair = new BasicNameValuePair(key, paraMap.get(key));
            values.add(pair);
        }
        return values;
    }

    private String getContent(HttpResponse response) {
        if (response == null) {
            return null;
        }
        HttpEntity httpEntity = response.getEntity();
        if (httpEntity == null) {
            return null;
        }
        String content = null;

        try {
            Charset charset = ContentType.getOrDefault(httpEntity).getCharset();
            content = EntityUtils.toString(httpEntity, charset);
        } catch (IOException e) {
            LogX.getLogX(getClass()).error("getContent error", e);
        } finally {
            IoUtil.closeHttpResponse(response);
        }
        return content;
    }

    public int getConnectionRequestTimeout() {
        return connectionRequestTimeout;
    }

    public void setConnectionRequestTimeout(int connectionRequestTimeout) {
        this.connectionRequestTimeout = connectionRequestTimeout;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public int getDefaultMaxPerRoute() {
        return defaultMaxPerRoute;
    }

    public void setDefaultMaxPerRoute(int defaultMaxPerRoute) {
        this.defaultMaxPerRoute = defaultMaxPerRoute;
    }

    public int getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public long getAutoCloseTimeout() {
        return autoCloseTimeout;
    }

    public void setAutoCloseTimeout(long autoCloseTimeout) {
        if (autoCloseTimeout <= 0 || autoCloseTimeout > 5000) {
            LogX.getLogX(getClass()).warn(String.format("autoCloseTimeout must be from %s to %s", 0, 5000));
            return;
        }
        this.autoCloseTimeout = autoCloseTimeout;
    }

}

 

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

/**
 * @author niuhaipeng
 *
 * @date 2015年12月17日
 */
public class CustomizedX509TrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }

}

maven配置

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.1</version>
        </dependency>

本文代码均可以从github下载地址 https://github.com/niuhp/toolbox

  • HttpClient
    8 引用 • 10 回帖
  • 登录
    17 引用 • 133 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • Apache
    27 引用 • 34 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 6 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 45 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 89 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖 • 3 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 429 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 126 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 34 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 11 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 192 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    96 引用 • 330 回帖 • 1 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 609 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 741 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 6 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 222 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 685 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 451 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    17 引用 • 236 回帖 • 417 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 592 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1398 回帖 • 1 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    103 引用 • 126 回帖 • 447 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 5 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 1 关注