httpclient学习文档
一、 httpclient 简介
官网: Apache HttpComponents – Apache HttpComponents 使用版本: 4.5.13
使用场景:
爬虫、多系统之间接口交互
二、JDK 原生api发送http请求
2.1 HttpURLConnection
import org.junit.jupiter.api.Test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
public class HttpURLCOnnTest {
/**
* 使用 jdk原生的API来请求网页
* @throws Exception
*/
@Test
public void jdkapi() throws Exception{
String urlStr = "https://www.baidu.com";
URL url = new URL(urlStr);
URLConnection urlConnection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
//设置请求类型
// 请求行、 空格、 请求头、 请求体
httpURLConnection.setRequestMethod("GET");
//请求头属性
httpURLConnection.setRequestProperty("Accept-Charset","utf-8");
//获取httpURLConnection 的输入流
try(
InputStream is = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
){
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
}
}
}
三、发送get请求
pom 依赖
<!--httpclient依赖-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
无参get请求
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class HttpClientTest {
/**
* 使用httpclient发送get请求
*/
@Test
public void testGet1(){
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://www.baidu.com";
//构造httpGet请求对象
HttpGet httpGet = new HttpGet(urlStr);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpGet);
//获取响应结果: DecompressingEntity,不仅可以作为结果,也可以作为参数实体,有很多实现
HttpEntity entity =response.getEntity();
//对HttpEntity操作的工具类
String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println(toStringResult);
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
伪装成浏览器:请求头的作用,防盗链
//加请求头, 解决http请求不认为真实请求 httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"); //加防盗链,vaule:要是发生防盗链网站的url httpGet.addHeader("Referer","https://www.baidu.com/");
有参数: 注意urlencode
获取响应头以及相应的content-type
下载网络图片到本地
/**
* 获取网络图片并保存到本地
*/
@Test
public void downloadPicture() throws Exception{
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://pics0.baidu.com/feed/4b90f603738da977ab03b9e0731a501f8718e39b.jpeg?token=47f4e2bbdd4a1fe91303ae4679f70a2d";
//构造httpGet请求对象
HttpGet httpGet = new HttpGet(urlStr);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpGet);
HttpEntity entity =response.getEntity();
String contentType = entity.getContentType().getValue();
String suffix = ".jpg";
if (contentType.contains("jpg")||contentType.contains("jpeg")){
suffix=".jpg";
}else if(contentType.contains("bmp")||contentType.contains("bitmap")){
suffix=".bmp";
}else if(contentType.contains("png")){
suffix=".png";
}else if(contentType.contains("gif")){
suffix=".gif";
}
//将entity转换为字节流
byte[] bytes = EntityUtils.toByteArray(entity);
//定义文件下载路径
String localAbsPath = "e:\\picture"+suffix;
FileOutputStream fos = new FileOutputStream(localAbsPath);
fos.write(bytes);
fos.close();
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
设置网络代理
/**
* 设置访问代理
* @throws Exception
*/
@Test
public void requestProxy() throws Exception {
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://www.baidu.com";
//构造httpGet请求对象
HttpGet httpGet = new HttpGet(urlStr);
//创建一个代理,可使用http://www.66ip.cn/ 寻找免费代理IP
String ip ="96.113.165.182";
int port=3128;
HttpHost proxy = new HttpHost(ip,port);
//对每一个请求进行配置,会覆盖全局的默认请求配置
RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();
httpGet.setConfig(requestConfig);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpGet);
//获取响应结果: DecompressingEntity,不仅可以作为结果,也可以作为参数实体,有很多实现
HttpEntity entity =response.getEntity();
//对HttpEntity操作的工具类
String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println(toStringResult);
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
设置连接超时和读取超时
/**
* 设置连接超时和读取超时
* @throws Exception
*/
@Test
public void setConnectTimeOut() throws Exception {
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://www.baidu.com";
//构造httpGet请求对象
HttpGet httpGet = new HttpGet(urlStr);
//创建一个代理,可使用http://www.66ip.cn/ 寻找免费代理IP
String ip ="96.113.165.182";
int port=3128;
HttpHost proxy = new HttpHost(ip,port);
//对每一个请求进行配置,会覆盖全局的默认请求配置
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //连接超时, ms, 完成tcp3次握手的时间上限
.setSocketTimeout(3000) //读取超时,ms, 表示从请求的网址处获得响应数据的时间间隔
.setConnectionRequestTimeout(5000) //从连接池里面获取connect的超时时间
.build();
httpGet.setConfig(requestConfig);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpGet);
//获取响应结果: DecompressingEntity,不仅可以作为结果,也可以作为参数实体,有很多实现
HttpEntity entity =response.getEntity();
//对HttpEntity操作的工具类
String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println(toStringResult);
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
四、发送post请求
使用httpclient发送application/x-www-form-urlencode类型的post请求
/**
* 使用httpclient发送application/x-www-form-urlencode类型的post请求
*/
@Test
public void postWithForm(){
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://www.baidu.com";
//构造httpGet请求对象
HttpPost httpPost = new HttpPost(urlStr);
//给post对象设置参数
List<NameValuePair> list = new ArrayList<>();
list.add(new BasicNameValuePair("username","post"));
list.add(new BasicNameValuePair("password","123"));
//把参数集合设置到formEntity
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);
//enetity设置内容类型
formEntity.setContentType(new BasicHeader("Content-Type","application/x-www-form-urlencode"));
httpPost.setEntity(formEntity);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpPost);
//获取响应结果: DecompressingEntity,不仅可以作为结果,也可以作为参数实体,有很多实现
HttpEntity entity =response.getEntity();
//对HttpEntity操作的工具类
String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println(toStringResult);
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
使用httpclient发送application/json类型的post请求
/**
* 使用httpclient发送application/json类型的post请求
*/
@Test
public void postWithJson(){
//可关闭的httpclient客户端,相当于你打开一个浏览器
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
String urlStr = "https://www.baidu.com";
//构造httpGet请求对象
HttpPost httpPost = new HttpPost(urlStr);
//给post对象设置参数
JSONObject jsonObject = new JSONObject();
jsonObject.put("userName","java");
jsonObject.put("password","123");
StringEntity jsonEntity = new StringEntity(jsonObject.toString(),Consts.UTF_8);
//enetity设置内容类型
jsonEntity.setContentType(new BasicHeader("Content-Type","application/json"));
//设置entity编码
jsonEntity.setContentEncoding(Consts.UTF_8.name());
httpPost.setEntity(jsonEntity);
//可关闭的响应
CloseableHttpResponse response =null;
try{
response = closeableHttpClient.execute(httpPost);
//获取响应结果: DecompressingEntity,不仅可以作为结果,也可以作为参数实体,有很多实现
HttpEntity entity =response.getEntity();
//对HttpEntity操作的工具类
String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println(toStringResult);
//确保流关闭
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(closeableHttpClient!=null){
try{
closeableHttpClient.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(response!=null){
try{
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
表单上传文件
AJAX的post请求与上传文件_端碗吹水的技术博客_51CTO博客_ajax上传文件
五、请求https链接
安全: https
不安全: http
解决方法:1、配置认证需要的秘钥配置httpclient
2、 配置httpclient绕过https安全认证
六、使用httpclient连接池
性能,提高程序的运行速度
连接的可复用性