使用 jdk1.8 lambda 表达式对 HttpClient 进行封装

本贴最后更新于 2476 天前,其中的信息可能已经时异事殊

1、使用 jdk lambda 表达式对 HttpClient 进行封装
2、HttpClient 的版本为 4.5.1
3、支持 http 和 https

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
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.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**

  • 说明: HttpClient 工具类
  • httpsclient 版本:4.5.1
  • @author xiaoting
  •     Created by 2017-04-06 13:56
    

/
public class HttpClientUtil {
/

* 日志
/
private static final Logger log = Logger.getLogger("lavasoft");
/
*
* 请求编码
/
private static final String CHARSET_UTF_8 = "UTF-8";
/
*
* json 头
/
private static final String CONTENT_TYPE_JSON = "application/json";
/
*
* xml 请求
/
private static final String CONTENT_TYPE_XML = "text/xml";
/
*
* 连接池
/
private static PoolingHttpClientConnectionManager connMgr;
/
*
* 请求配置
*/
private static RequestConfig requestConfig;

/**
 * 超时时间
 */
private static final int MAX_TIMEOUT = 7000;

static {
    // 设置连接池
    connMgr = new PoolingHttpClientConnectionManager();
    // 设置连接池大小
    connMgr.setMaxTotal(100);
    connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
    /*校验链接*/
    connMgr.setValidateAfterInactivity(1000);
    RequestConfig.Builder configBuilder = RequestConfig.custom();
    // 设置连接超时
    configBuilder.setConnectTimeout(MAX_TIMEOUT);
    // 设置读取超时
    configBuilder.setSocketTimeout(MAX_TIMEOUT);
    // 设置从连接池获取连接实例的超时
    configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
    requestConfig = configBuilder.build();
}

/**
 * 发送get请求
 *
 * @param url url
 * @return
 */
public static String get(String url) {
    return doGet(url, new HashMap<>());
}

/**
 * 发送get请求
 *
 * @param url url
 * @return
 */
public static String getHttps(String url) {
    return doGet(url, new HashMap<>(), false);
}

/**
 * 发送get请求 https
 *
 * @param url url
 * @return
 */
public static String getHttps(String url, Map<String, Object> params) {
    return doGet(url, params, false);
}

public static String doGet(String url, Map<String, Object> params, boolean bl) {
    log.info("____请求参数:" + params.toString());
    String param = getStringBuffer(params);
    String finalApiUrl = url + param;
    return HttpClient.domain(httpClient -> {
        HttpGet httpGet = new HttpGet(finalApiUrl);
        return execute(httpClient, httpGet);
    }, bl);
}

/**
 * 发送 GET 请求(HTTP),K-V形式
 *
 * @param url
 * @param params
 * @return
 */
public static String doGet(String url, Map<String, Object> params) {
    return doGet(url, params, true);
}

private static String getStringBuffer(Map<String, Object> params) {
    if (MapUtil.isNotNull(params)) {
        StringBuffer param = new StringBuffer();
        int i = 0;
        for (String key : params.keySet()) {
            if (i == 0) {
                param.append("?");
            } else {
                param.append("&");
            }
            param.append(key).append("=").append(params.get(key));
            i++;
        }
        return param.toString();
    } else {
        return "";
    }
}

/**
 * 发送post请求
 *
 * @param url    post url
 * @param params post参数
 * @return
 */
public static String post(String url, Map<String, Object> params) {
    log.info("____请求参数:" + params.toString());
    return HttpClient.domain(httpClient -> {
        HttpPost httpPost = httpPostHandler(url, params);
        return execute(httpClient, httpPost);
    }, true);
}

/**
 * 发送post请求
 *
 * @param url post url
 * @return
 */
public static String post(String url) {
    return post(url, new HashMap<>());
}

/**
 * post json数据
 *
 * @param url
 * @param jsonStr
 * @return
 */
public static String postJson(String url, String jsonStr) {
    log.info("____请求参数:" + jsonStr);
    return HttpClient.domain(httpClient -> {
        HttpPost httpPost = new HttpPost(url);
        StringEntity stringEntity;
        try {
            stringEntity = new StringEntity(jsonStr);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
        httpPost.setHeader("Content-Type", CONTENT_TYPE_JSON);
        httpPost.setEntity(stringEntity);
        return execute(httpClient, httpPost);
    }, true);
}

/**
 * 发送 SSL POST 请求(HTTPS),K-V形式
 *
 * @param apiUrl API接口URL
 * @param params 参数map
 * @return
 */
public static String doPostSSL(String url, Map<String, Object> params) {
    log.info("____请求参数:" + params.toString());
    return HttpClient.domain(httpClient -> {
        HttpPost httpPost = httpPostHandler(url, params);
        return execute(httpClient, httpPost);
    }, false);
}

/**
 * 发送 SSL POST 请求(HTTPS),JSON形式
 *
 * @param apiUrl API接口URL
 * @param json   JSON对象
 * @return
 */
public static String doPostSSL(String apiUrl, Object json) {
    log.info("____请求参数:" + json);
    return HttpClient.domain(httpClient -> {
        HttpPost httpPost = new HttpPost(apiUrl);
        StringEntity stringEntity;
        stringEntity = new StringEntity(json.toString(), CHARSET_UTF_8);
        stringEntity.setContentEncoding(CHARSET_UTF_8);
        httpPost.setHeader("Content-Type", CONTENT_TYPE_JSON);
        httpPost.setEntity(stringEntity);
        return execute(httpClient, httpPost);
    }, false);
}

/*
public static String postXml(String url, Object xmlObj) {
    String res = null;
    CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
        HttpPost httpPost = new HttpPost(url);
        //解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", CONTENT_TYPE_XML);
        httpPost.setEntity(postEntity);
        res = execute(httpClient, httpPost);
    } finally {
        doHttpClientClose(httpClient);
    }
    return res;
}*/
private static HttpPost httpPostHandler(String url, Map<String, Object> params) {
    HttpPost httpPost = new HttpPost(url);
    List<NameValuePair> naps = new ArrayList<>();
    if (MapUtil.isNotNull(params)) {
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            naps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }
    }
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(naps, CHARSET_UTF_8));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return httpPost;
}

private static String execute(CloseableHttpClient httpClient, HttpRequestBase httpGetOrPost) {
    String res = null;
    CloseableHttpResponse response = null;
    try {
        httpGetOrPost.setConfig(requestConfig);
        log.info("________请求url:" + httpGetOrPost.getURI());
        response = httpClient.execute(httpGetOrPost);
        log.info("________返回code:" + response.getStatusLine().getStatusCode());
        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            return null;
        }
        HttpEntity entity = response.getEntity();
        res = EntityUtils.toString(entity, CHARSET_UTF_8);
        log.info("________返回值:" + res);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        doResponseClose(response);
    }
    return res;
}

private static void doHttpClientClose(CloseableHttpClient httpClient) {
    if (httpClient != null) {
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private static void doResponseClose(CloseableHttpResponse response) {
    if (response != null) {
        try {
            response.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public interface HttpClientInterface<T> {
    T domain(CloseableHttpClient httpClient);
}

static class HttpClient {
    /**
     * @param interfaces 具体的操作接口
     * @param bl         是否是http请求,false https true http
     * @param <T>        返回泛型
     * @return
     */
    public static <T extends Object> T domain(HttpClientInterface<T> interfaces, boolean bl) {
        // 返回值
        T object;
        CloseableHttpClient httpClient;
        if (bl) {
            httpClient = HttpClients.createDefault();
        } else {
            httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).
                    setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).
                    setConnectionManagerShared(true).build();
        }
        try {
            // 业务操作
            object = interfaces.domain(httpClient);
        } finally {
            doHttpClientClose(httpClient);
        }
        return object;
    }
}

/**
 * 创建SSL安全连接
 *
 * @return
 */
private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
    SSLConnectionSocketFactory sslsf = null;
    try {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();
        sslsf = new SSLConnectionSocketFactory(sslContext, (arg0, agr1) -> true);
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    }
    return sslsf;
}

}

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1083 引用 • 3461 回帖 • 287 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • MyBatis

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

    170 引用 • 414 回帖 • 426 关注
  • OnlyOffice
    4 引用 • 19 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 109 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 2 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 30 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    27 引用 • 66 回帖 • 1 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 370 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    83 引用 • 165 回帖 • 40 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 349 关注
  • TGIF

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

    284 引用 • 4481 回帖 • 654 关注
  • SQLServer

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

    19 引用 • 31 回帖 • 5 关注
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 497 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 193 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • QQ

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

    45 引用 • 557 回帖 • 218 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 8 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 462 关注
  • SQLite

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

    4 引用 • 7 回帖
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    22 引用 • 31 回帖 • 3 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 470 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    21 引用 • 58 回帖
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 602 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 23 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖 • 1 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 1 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 687 关注