基于apache httpclient的http访问工具

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

代码是对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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3206 引用 • 8217 回帖
  • Apache
    27 引用 • 35 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    63 引用 • 289 回帖 • 1 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 27 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 11 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 548 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 838 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    135 引用 • 798 回帖 • 2 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    188 引用 • 833 回帖 • 2 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    168 引用 • 598 回帖
  • CodeMirror
    2 引用 • 17 回帖 • 197 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    203 引用 • 4024 回帖
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    70 引用 • 193 回帖 • 404 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    43 引用 • 130 回帖 • 259 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    695 引用 • 538 回帖 • 2 关注
  • Outlook
    1 引用 • 5 回帖 • 1 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    200 引用 • 545 回帖
  • Visio
    1 引用 • 2 回帖
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 430 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    599 引用 • 3541 回帖
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 429 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    293 引用 • 4496 回帖 • 688 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 99 关注
  • Folo

    Folo 是一个 RSS 阅读和信息聚合应用,整合多种内容源到统一时间线。

    项目地址:https://github.com/RSSNext/Folo

    1 引用 • 3 回帖 • 2 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有机会重制。

    14 引用 • 258 回帖
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 1 关注