java处理http请求之Apache httpClient入门教程
说明
本文示例代码基于 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
项目,它包括 HttpClient
和 HttpCore
两大模块,能提供更好的性能和更大的灵活性。
二、项目模块
Apache Httpcomponents
项目包括 HttpClient
和 HttpCore
两大模块,其中,HttpCore
是一套HTTP协议实现包。而 HttpClient
是基于HttpCore的一套客户端。
三、使用方式
使用 Httpclient
需要经过如下步骤
- 创建
HttpClient
- 创建 http 请求,如
HttpGet
、HttpPost
- 添加请求参数
- 添加请求设置,如超时等
- 使用
HttpClient
执行 http 请求 - 读取返回内容并释放连接
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 请求
创建 HttpGet
、HttpPost
请求
@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 |
注意:
socketTimeout
和connectionRequestTimeout
如果不设置,请求会阻塞。但是
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入门教程的更多相关文章
- Apache Solr入门教程(初学者之旅)
Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各方面,建议边思考边实践,相信能帮助你对solr有个清晰全面的了解并能简单实用. 在Apache Solr初学者教程的这个 ...
- Java 图片处理解决方案:ImageMagick 快速入门教程
文章首发于[博客园-陈树义],点击跳转到原文Java 图片处理解决方案:ImageMagick 快速入门教程. ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件 ...
- HttpClient 入门教程学习
HttpClient简介 HttpClient是基于HttpCore的HTTP/1.1兼容的HTTP代理实现. 它还为客户端认证,HTTP状态管理和HTTP连接管理提供可重用组件. HttpCompo ...
- 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈
在日常业务代码开发中,我们经常接触到AOP,比如熟知的Spring AOP.我们用它来做业务切面,比如登录校验,日志记录,性能监控,全局过滤器等.但Spring AOP有一个局限性,并不是所有的类都托 ...
- Apache Solr入门教程(转)
1.为什么选择Apache Solr Apache Solr是一个功能强大的搜索服务器,它支持REST风格API.Solr是基于Lucene的,Lucene 支持强大的匹配能力,如短语,通配符,连接, ...
- HttpClient入门教程
HttpClient使用详解与实战一:https://www.jianshu.com/p/375be5929bed
- RESTful Java client with Apache HttpClient / URL /Jersey client
JSON example with Jersey + Jackson Jersey client examples RESTful Java client with RESTEasy client f ...
- java springboot整合zookeeper入门教程(增删改查)
java springboot整合zookeeper增删改查入门教程 zookeeper的安装与集群搭建参考:https://www.cnblogs.com/zwcry/p/10272506.html ...
- Java 图片处理解决方案:ImageMagick 快速入门
一.ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件,可以实现图片切割.颜色替换.图片缩略图.图片水印等各种效果.ImageMagick是免费开源软件,支持大多 ...
- 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 ...
随机推荐
- centos 8 mysql 更改数据存储位置
登录mysql后,先切换到myql数据库下通过show global variables like '%datadir%'; 可以查看数据默认的存储路径(一般在 /var/lib/mysql) 新建数 ...
- 历时两天半由浅入深总结了20道Vue高频面试题
作为一个程序员如果你想要找到你心仪的工作,不可避免的就会问到很多八股文,虽然有的和工作没有半毛钱关系,但是你如果想要通过面试还必须得会.所以我最近开始总结一些面试题,一是为了加强自己的理解能够找到一份 ...
- 5. 想在代码中验证sql的正确性?
1. 简介 我们在平时的开发中可能会遇到需要验证一下sql是否正确,也就是需要check一下sql. 判断sql是否正确一般包含一下几点: 1. sql中使用的列是否存在 2. sql语法是否正确 3 ...
- Leetcode 236. 二叉树的最近公共祖先 & 235. 二叉搜索树的最近公共祖先(Python3)
236. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x ...
- QT5笔记: 32. QPainter 基本绘制
- Typecho Mirages 主题自定义公告样式
使用步骤 将以下代码加入到 <head> 标签中.对于本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head ...
- mysql常用函数、查询和事务说明笔记
1.MySQL中内置了很多字符串函数,常用的几个如下: 运用示例:示例表里初始数据: 字段title和titleImage concat : 字符串拼接 select concat(title,tit ...
- AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
引言 在当今这个数据爆炸的时代,信息的快速存储与高效检索已经成为技术领域的核心挑战.随着人工智能(AI)和机器学习(ML)的迅猛发展,向量存储和相似性搜索技术逐渐崭露头角,成为处理海量数据的利器.对于 ...
- 音视频SDK对比|K歌App中的实时合唱功能如何进行技术选型
摘要 在线K歌软件的开发有许多技术难点,需考虑到音频录制和处理.实时音频传输和同步.音频压缩和解压缩.设备兼容性问题等技术难点外,此外,开发者还应关注音乐版权问题,确保开发的应用合规合法. 前言 前面 ...
- 一个专业DBA应具备的技能
本文可以作为MySQL DBA面试官,以及候选人的双向参考 面试流程 接下来先说下我以往在做MySQL DBA面试时的过程(套路): 1.先自我介绍后,再让候选人花2-5分钟做下自我简介有不少人可能对 ...