说明

本文示例代码基于 4.5.13 版本

转载请注明出处:https://www.cnblogs.com/qnlcy/p/15378446.html

一、项目介绍

Apache 提供用来做http请求的项目有两个,3.x 版本的项目叫做 The Commons HttpClient

它一开始是 Apache Jakarta Common 下的子项目,后来独立出去了,现在这个项目已经结束了它的生命周期,不再开发和维护。

取而代之的是 4.x 版本的 Apache Httpcomponents 项目,它包括 HttpClientHttpCore 两大模块,能提供更好的性能和更大的灵活性。

二、项目模块

Apache Httpcomponents 项目包括 HttpClientHttpCore 两大模块,其中,HttpCore 是一套HTTP协议实现包。而 HttpClient 是基于HttpCore的一套客户端。

三、使用方式

使用 Httpclient 需要经过如下步骤

  1. 创建 HttpClient
  2. 创建 http 请求,如 HttpGetHttpPost
  3. 添加请求参数
  4. 添加请求设置,如超时等
  5. 使用 HttpClient 执行 http 请求
  6. 读取返回内容并释放连接

3.1 创建 HttpClient

3.1.1 创建默认客户端:

    CloseableHttpClient httpclient = HttpClients.createDefault();

一些重要的默认配置:

  • 默认连接池大小10,每域名最大连接5
  • 连接池中连接存活时间 connTimeToLive = -1 ,默认单位为毫秒,默认连接不失效
  • 域名验证器为 DefaultHostnameVerifier , 会验证域名
  • SSL 上下文为 SSLContext.getInstance("TLS"),没有使用密钥管理器(KeyManager)和信任管理器(TrustManager)

3.1.2 自定义客户端

  • 失败不重试
    CloseableHttpClient client = HttpClients.custom().setRetryHandler((e, i, c) -> false).build();
  • 自定义连接池
 //设置自定义连接池
@Test
public void customConnectionPool() throws Exception {
//1.创建 https 需要的 SslContext 相关内容
//1.1 创建 SslContext
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream("证书文件"), "密码".toCharArray());
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(TrustAllStrategy.INSTANCE)
.loadKeyMaterial(ks, "证书密码".toCharArray()).build();
//1.2 创建 SSLConnectionSocketFactory
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv3", "TLSv1.1", "TLSv1.2"}, null,
NoopHostnameVerifier.INSTANCE); //2.创建连接池
//2.1 构建协议 registry
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);
//3.连接池针对所有连接、每域名的连接的数量设置
poolingHttpClientConnectionManager.setMaxTotal(100);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20); //4.创建client
CloseableHttpClient client =
HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build();
}

3.2 创建 Http 请求

创建 HttpGetHttpPost 请求

    @Test
public void getAndPost(){
//1.创建get请求
HttpGet get = new HttpGet("https://www.baidu.com"); //2.创建post请求
HttpPost post = new HttpPost("https://www.baidu.com"); //3.其他如 HttpPut、HttpOptions、HttpTrace、HttpDelete、HttpPatch
}

3.3 添加请求参数

    @Test
public void addParams() throws IOException {
HttpPost post = new HttpPost("https://www.baidu.com");
//1.底层流,基础参数
BasicHttpEntity basicHttpEntity = new BasicHttpEntity();
//1.1添加参数内容
InputStream bis = new ByteArrayInputStream("参数".getBytes());
basicHttpEntity.setContent(bis);
//1.2设置内容长度
basicHttpEntity.setContentLength(bis.available());
//1.3取消分块发送
basicHttpEntity.setChunked(false);
post.setEntity(basicHttpEntity); //2.字节码类型参数
HttpEntity entity = new ByteArrayEntity("name=zhangsan&age=100".getBytes());
post.setEntity(entity); //3.字符串类型参数
entity = new StringEntity("name=zhangsan&age=100");
post.setEntity(entity); //4.流式参数,用法与BasicHttpEntity类似,内容和长度严格匹配
entity = new InputStreamEntity(bis,bis.available());
post.setEntity(entity); //5.文件类型参数
entity = new FileEntity(new File("上传文件"));
post.setEntity(entity); //6.添加请求头
post.addHeader("Content-Type","text/html;charset=UTF-8"); Header contentType = new BasicHeader("Content-Type","text/html;charset=UTF-8");
post.addHeader(contentType); Header host = new BasicHeader("Host","www.baidu.com");
post.setHeaders(new Header[]{contentType,host}); }

3.4 添加请求设置

    @Test
public void requestConfig(){
//1.配置RequestConfig
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(10000) //从连接池获取可用连接的超时时间,单位毫秒
.setSocketTimeout(5000) //请求获取数据的超时时间
.setConnectTimeout(4000) //连接超时时间
.build();
HttpPost post = new HttpPost("https://www.baidu.com");
//2.设置到post请求当中
post.setConfig(requestConfig); //也可以当作默认值,设置到client当中,此client都会按这个超时处理
CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
}

3.4.1 超时时间说明

超时类型 说明
connectionTimeout 连接建立时间,即3次握手时间,默认值-1
socketTimeout 连接后,数据传输过程中数据包之间间隔的最大时间,默认值-1
connectionRequestTimeout 从连接池获取连接的超时时间,默认值-1

注意:

socketTimeoutconnectionRequestTimeout 如果不设置,请求会阻塞。

但是 connectionTimeout 的情况有所不同,它依赖于各平台的 socket 超时时间设置。

windows 10 实测为 20s, linux 平台则不定,它会按 /proc/sys/net/ipv4/tcp_syn_retries 中配置的次数重试,一般为3s\7s\15s\31s\63s递增

另外,即使 java 程序返回了超时结果,但是linux服务器依旧在执行重试直到服务器端超时,为了提高资源利用率,可以手动关闭

关于 linux socket 超时的问题,请参阅 无毁的湖光-Al从linux源码看socket(tcp)的timeout

3.5 执行 http 请求

执行 http 请求比较简单,直接调用 execute() 方法即可

    @Test
public void execute(){
CloseableHttpClient client = HttpClients.createDefault();
try {
client.execute(new HttpPost("https://www.baidu.com"));
client.execute(new HttpGet("https://www.baidu.com"));
} catch (IOException e) {
e.printStackTrace();
}
}

3.6 读取返回内容并释放连接

服务器返回结果被封装到 HttpResponse 对象里,我们可以从这里拿到我们想要的返回结果

    @Test
public void getResponse() {
CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
final HttpGet httpGet = new HttpGet("https://www.baidu.com");
try {
httpResponse = client.execute(httpGet);
//1.获取返回状态
System.out.println(httpResponse.getStatusLine().getStatusCode());
//2.获取返回头信息
Header[] headers = httpResponse.getAllHeaders();
for (Header header : headers) {
System.out.println(header.getName() + ":" + header.getValue());
}
//3.获取返回消息体
HttpEntity entity = httpResponse.getEntity();
if(null != entity){
//3.1 得到返回结果并关闭流,与下面的只能执行一个,因为流只能读取一次
String content = EntityUtils.toString(entity);
System.out.println(content);
//3.2 得到返回结果并关闭流,与上面的只能执行一个
// byte[] contents = EntityUtils.toByteArray(entity);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != httpResponse) {
//4.归还连接到连接池
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//如果复用 httpGet ,则重置其状态使其可以重复使用
httpGet.releaseConnection();
} //只在应用关闭的时候关闭client
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}

java处理http请求之Apache httpClient入门教程的更多相关文章

  1. Apache Solr入门教程(初学者之旅)

    Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各方面,建议边思考边实践,相信能帮助你对solr有个清晰全面的了解并能简单实用. 在Apache Solr初学者教程的这个 ...

  2. Java 图片处理解决方案:ImageMagick 快速入门教程

    文章首发于[博客园-陈树义],点击跳转到原文Java 图片处理解决方案:ImageMagick 快速入门教程. ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件 ...

  3. HttpClient 入门教程学习

    HttpClient简介 HttpClient是基于HttpCore的HTTP/1.1兼容的HTTP代理实现. 它还为客户端认证,HTTP状态管理和HTTP连接管理提供可重用组件. HttpCompo ...

  4. 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈

    在日常业务代码开发中,我们经常接触到AOP,比如熟知的Spring AOP.我们用它来做业务切面,比如登录校验,日志记录,性能监控,全局过滤器等.但Spring AOP有一个局限性,并不是所有的类都托 ...

  5. Apache Solr入门教程(转)

    1.为什么选择Apache Solr Apache Solr是一个功能强大的搜索服务器,它支持REST风格API.Solr是基于Lucene的,Lucene 支持强大的匹配能力,如短语,通配符,连接, ...

  6. HttpClient入门教程

    HttpClient使用详解与实战一:https://www.jianshu.com/p/375be5929bed

  7. RESTful Java client with Apache HttpClient / URL /Jersey client

    JSON example with Jersey + Jackson Jersey client examples RESTful Java client with RESTEasy client f ...

  8. java springboot整合zookeeper入门教程(增删改查)

    java springboot整合zookeeper增删改查入门教程 zookeeper的安装与集群搭建参考:https://www.cnblogs.com/zwcry/p/10272506.html ...

  9. Java 图片处理解决方案:ImageMagick 快速入门

    一.ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件,可以实现图片切割.颜色替换.图片缩略图.图片水印等各种效果.ImageMagick是免费开源软件,支持大多 ...

  10. Java之网络请求工具类(依赖:org.apache.http;注:HttpClient 4.4,HttpCore 4.4)

    到此处可以去下载依赖包:http://hc.apache.org/downloads.cgi import java.util.List; import org.apache.http.HttpSta ...

随机推荐

  1. hibernate基础查询语句使用

    hibernate最新文档 项目仓库地址项目201102-hibernateSelect 数据准备 -- 创建数据表 drop table if exists t_book; create table ...

  2. [THUSC2015] 异或运算 题解

    学到新思路了:求解 \(k\) 大值时,可以将所有元素放一块一起跑. 考虑到 \(n,q\) 奇小无匹,我们便可以制造一个 \(O(qn\log V)\) 的代码. 那么对于我们不想在时间复杂度中出现 ...

  3. QT5笔记:36. QGraphicsView 综合示例 (完结撒花!)

    通过此示例可以比较熟悉QGraphincsView的流程以及操作 坐标关系以及获取: View坐标:左上角为原点,通过鼠标移动事件获取 Scene坐标:中心为原点,横竖为X,Y轴.通过View.map ...

  4. C#中固定编译时不确定数量的变量(相关话题fixed固定多个数组)

    以交错数组byte[][]为例. fixed无法固定byte[][],只能在编译时固定确定数量的变量. 交错数组byte[][]中的每一个byte[]可以采用GCHandle进行固定. int n = ...

  5. Codeforces Round 1006 (Div. 3) 比赛记录

    Codeforces Round 1006 (Div. 3) 比赛记录 比赛链接 这场的题目名称都很长啊~. 很简单的一场(毕竟是div3,能不简单嘛)赛时切掉了A - F,C题花的时间有点多,G题偶 ...

  6. 循环(Java篇)

    令人头痛的循环(:´д`)ゞ 我们在学习循环的时候可能会有点懵,什么是循环?它可以干嘛?我这里为什么要用循环来写这段代码?等问题. 首先我们来讲一下循环可以干嘛 循环是什么?o(′益`)o 在 Jav ...

  7. How to use the shell, terminal and the advanced tools

    How to use the shell, terminal and the advanced tools Introduction ‍ Why use English instead of Chin ...

  8. DBeaver 连接 mysql 报错:Public Key Retrieval is not allowed

    前言 DBeaver 连接 mysql 报错:Public Key Retrieval is not allowed 遇到 "Public Key Retrieval is not allo ...

  9. docker删除所有服务service,停止并删除所有容器container

    查看运行容器docker ps 查看所有容器docker ps -a 进入容器其中字符串为容器ID:docker exec -it d27bd3008ad9 /bin/bash 删除所有服务:dock ...

  10. SpringBoot + 布隆过滤器:亿级数据下的高效防护盾与缓存穿透实战指南

    在当今高并发.海量数据的应用场景中,布隆过滤器凭借其极低的内存占用和极快的查询效率,成为解决缓存穿透.数据预判等难题的利器.本文深度解析布隆过滤器的核心原理与实战应用,手把手教你如何将这一数据守门员融 ...