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 ...
随机推荐
- MOS管的寄生电容
我们经常看到,在电源电路中,功率MOS管的G极经常会串联一个小电阻,几欧姆到几十欧姆不等,那么这个电阻用什么作用呢? 这个电阻的作用有2个作用:限制G极电流,抑制振荡. 限制G极电流MOS管是由电压驱 ...
- openlayers 在地图上绘制矩形框,非鼠标框选
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title d ...
- 个人文件转移工具-来自某位大神的C盘清理神器
软件名称:个人文件转移工具 软件功能:文件转移 支持平台:Windows 软件简介:一款文件转移工具,也可用作C盘瘦身. 软件特点: ◉ "个人文件转移工具"可以把"我的 ...
- 迅速理解 LCS 最长公共子序列问题
在算法与数据结构的经典问题中,最长公共子序列(Longest Common Subsequence,简称 LCS)问题占据着重要的地位.给定两个序列,我们需要找到它们最长的公共子序列,而子序列要求保持 ...
- AI与.NET技术实操系列(八):使用Catalyst进行自然语言处理
引言 自然语言处理(Natural Language Processing, NLP)是人工智能领域中最具活力和潜力的分支之一.从智能客服到机器翻译,再到语音识别,NLP技术正以其强大的功能改变着我们 ...
- 查询Oracle正在执行的sql语句及执行该语句的用户
SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, paddr, sql_text 正在执行的SQL, b.m ...
- MD5加密BASE64加解密
MD5需要引入system.Hash,BASE64需要引入System.NetEncoding,这两个单元应该只有高版本的DELPHI IDE才有 (貌似XE5以上版本才有).如果是D7的话,找第三方 ...
- 开发app步骤总结
以下是用IDEA后端Java开发(如Spring Boot)与Android Studio前端开发app的逻辑实现步骤详解: 一.技术选择 通信协议:推荐使用RESTful API(HTTP/HTTP ...
- object中的usemap是什么-HTML
<object> 标签中的 usemap 属性用于将嵌入的对象(如图像)与一个 图像映射(image map) 关联起来.图像映射允许你在图像的特定区域定义可点击的链接,用户点击这些区域时 ...
- 离线版nrfutil工具安装方法
简介 nrfutil是Nordic提供的命令行工具集.支持以下功能: 基于Jlink的固件烧录.读取.flash擦除.recover 基于MCUBOOT的固件升级(DFU) 基于nRF5 bootlo ...