说明

本文示例代码基于 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. SnowFlake雪花算法

    简介 自然界不存在两片完全一样的雪花,每一片都是独一无二的,雪花算法的命名由此而来,所有雪花算法表示生成的ID唯一,且生成的ID是按照一定的结构组成. 组成结构 上图可以看到雪花算法的结构由四部分组成 ...

  2. min-max 容斥(最值反演)学习笔记

    min-max 容斥,又名最值反演(我其实更喜欢后面这个名字),是一种常用的反演思想. 引入 在皇后游戏一题中,我们曾经证明过 \(\max(a,b)-a-b=-\min(a,b)\). 我们尝试推广 ...

  3. android studio真机调试华为手机

    背景 近来开发一个视频通话App,需要在华为手机上调试,按网上一顿操作,开启了USB调试之后,发现手机连上电脑后,android studio没反应,在此记录下解决方法.调试的手机型号是华为 nova ...

  4. 解决 Docker 安装时“无法获取 dpkg 前端锁”错误的有效方法

    在安装 Docker 的过程中,不少用户可能会遇到"无法获取 dpkg 前端锁"的错误提示.这是一个较为常见但也令人困扰的问题.下面为您详细介绍几种可能的解决方法: 方法一:检查并 ...

  5. 离线安装Docker社区版详细教程

    Docker是一个开源的应用容器引擎,使得开发者可以打包应用以及依赖包到一个轻量级的.可移植的容器中,然后发布到任何支持Docker的平台上.本文将详细介绍如何在离线环境下安装Docker社区版. 1 ...

  6. 小米字体和思源宋体CSS调用使用指南

    小米字体 //css引用 <link rel="stylesheet" href="https://font.sec.miui.com/font/css?famil ...

  7. CUDA时长统计

    技术背景 前面的一篇文章中介绍了在CUDA中使用宏来监测CUDA C函数或者Kernel函数的运行报错问题.同样的思路,我们可用写一个用于统计函数运行时长的宏,这样不需要使用额外的工具来对函数体的性能 ...

  8. 【资源分享】Latex mathematical symbol

    https://files.cnblogs.com/files/blogs/705982/symbols.zip?t=1660463874 上面这个是pdf版,把这个压缩包下载之后,后缀改为pdf即可 ...

  9. CMD批处理脚本+VBScript脚本+Potplayer 实现文件夹内所有视频的截图任务(指定时间点)

    实现自动化视频截图,一般会直接借视频编解码如FFmpeg,动用相关函数来实现,直接从解码源头设计程序.然而我没有接触过FFmpeg,借助cmd批处理,以及vbs,还有现成的播放器potplayer,一 ...

  10. etcd 快速入门

    一.认识etcd 1.1 etcd 概念 从哪里说起呢?官网第一个页面,有那么一句话: "A distributed, reliable key-value store for the mo ...