文档D:\httpclient-demo

官网:Apache HttpComponents – Apache HttpComponents

常见使用场景:1.爬虫(python相对做爬虫专业,但是java也可以做)  2.与其他应用进行交互时候

注意下,不同的HttpClient的jar包版本,API和包路径有明显不同

先使用JDK原生API请求网页

将控制台的复制保存为html文件

双击打开

request:请求行,请求头,请求体

可以设置请求方式,请求头,等

依赖

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>

演示使用HttpClient发送get请求,无参

@Testpublic void test1(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();String str="https://www.baidu.com";//构造HttpGet请求对象HttpGet httpGet=new HttpGet(str);//声明可关闭响应对象CloseableHttpResponse response = null;try {//可关闭的httpclient客户端对象执行httpGet请求response=closeableHttpClient.execute(httpGet);//获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体//作为响应结果的实现类是DecompressingEntityHttpEntity httpEntity=response.getEntity();//对HttpEntity操作的工具类String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);System.out.println(toStringResult);//确保流关闭EntityUtils.consume(httpEntity);} catch (Exception e) {e.printStackTrace();}finally {if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}if(closeableHttpClient!=null){try {closeableHttpClient.close();} catch (IOException e) {e.printStackTrace();}}}}}

控制台打印结果和原先一样

关于user-agent和referer:

user-agent意思是用户代理:客户端用的什么浏览器

假如一直用Httpclient连接某些网页,如果对方知道你是机器所为

比如下面这样

可以在请求头里设置user-agent

比如在请求对象里设置:

//构造HttpGet请求对象
HttpGet httpGet=new HttpGet(str);
httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");

这样一般可以解决httpClient被认为不是真人行为

另外网站为了保护自己,比如爬对方图片,进行防盗链设置

而Referer是用来,解决网站防盗链

每个请求头,都有对应的作用,自己可查看资料

下面演示,一个网站通过浏览器访问后端,后端获取所有请求头,和通过HttpClien发送请求,所得到的请求头有哪些不一样。

该demo一会上传百度云盘

前端就几个表单,做为参数通过get,post,还有文件上传的演示

后端接收,并打印所有由浏览器发起请求的所有请求头

随便用户名,密码,这里输入aaa,密码 bbb 后端得到的所有请求头

且账号密码  都是Okde

然后再实验 账户aaa,密码aaa+bbb

再来看看用HttpClien发送该请求,后端的结果

也用 aaa  bbb

HttpClient代码  主要注意一点,就是表单提交时候 比如用户名是aaa+bbb的时候,会自动帮我们编码

而如果用HttpClient直接将用户名aaa+bbb  密码xxx这样进行提交的话,后台收到的+号会变空格,甚至说比如空格等特殊符号,直接给你报错了,就是说不让你用HttpClient提交该请求

比如String str=http://localhost:8899/httpclient-demo/test1?userName=aaa  空格  Bbbb&password=bbb

就直接给你报错

 /*** 使用httpclient发送get请求*/@Testpublic void test1(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();//String str="http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb";String str="http://localhost:8899/httpclient-demo/test1?userName="+"aaa+bbb"+"&password=bbb";//构造HttpGet请求对象HttpGet httpGet=new HttpGet(str);httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");//httpGet.addHeader("Referer","http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb");//声明可关闭响应对象CloseableHttpResponse response = null;try {//可关闭的httpclient客户端对象执行httpGet请求response=closeableHttpClient.execute(httpGet);//获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体//作为响应结果的实现类是DecompressingEntityHttpEntity httpEntity=response.getEntity();//对HttpEntity操作的工具类String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);System.out.println(toStringResult);//确保流关闭EntityUtils.consume(httpEntity);} catch (Exception e) {e.printStackTrace();}finally {if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}if(closeableHttpClient!=null){try {closeableHttpClient.close();} catch (IOException e) {e.printStackTrace();}}}}}

报错的演示

想说明的一点是,用浏览器提交表单请求时候,浏览器会帮我们自动对中文和特殊符号进行编码,后端会自行解码,但是当使用HttpClient的时候用注意中文和特殊符号

那么就要将到URLEncode  它可以对RUL上的特殊字符进行编码

用浏览器,提交时候会自动完成URLEncode 而当使用HttpClient时候,中文与特殊符号就需要我们自己使用URLEncode进行编码

丫的CSDN不能上传图片了

就是用URLEncode对get请求进行编码即可

String str="http://localhost:8899/httpclient-demo/test1?userName=   "+"aaa+bbb"+"&password=bbb";
try {str=URLEncoder.encode(str, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {e.printStackTrace();
}

这里注意一点,上面这么做是错的

由于一时没法发图片,这么做的话,会将整个url全部编码,也就是说://  &  ?等等全部进行了编码

而我们只需要对我们上传的参数进行编码,因此正确做法是

lic void test1(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();//String str="http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb";String userName="aaa 哈哈";String password="你妹";try {//对自定义上传的进行编码userName=URLEncoder.encode(userName, StandardCharsets.UTF_8.name());password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());} catch (Exception e) {e.printStackTrace();}String str="http://localhost:8899/httpclient-demo/test1?+userName="+userName+"&password="+password;

对HttpClient做了些改动,没法发图说明,全复制了一遍

/*** 使用httpclient发送get请求*/@Testpublic void test1(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();String userName="收到 你没";String password="阿斯顿)(";try {userName= URLEncoder.encode(userName, StandardCharsets.UTF_8.name());password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());} catch (Exception e) {e.printStackTrace();}String str="http://localhost:8899/httpclient-demo/test1?userName="+userName+"&password="+password;//构造HttpGet请求对象HttpGet httpGet=new HttpGet(str);httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");//httpGet.addHeader("Referer","https://www.amamaw.com");//声明可关闭响应对象CloseableHttpResponse response = null;try {//可关闭的httpclient客户端对象执行httpGet请求response=closeableHttpClient.execute(httpGet);//代表本次请求成功或者失败的状态StatusLine statusLine=response.getStatusLine();if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等System.out.println("响应成功");//获取所有响应头Header[] allHeader=response.getAllHeaders();for(Header header:allHeader){System.out.println("响应头:"+header.getName()+":"+header.getValue());}//成功了再获取响应结果//获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体//作为响应结果的实现类是DecompressingEntityHttpEntity httpEntity=response.getEntity();System.out.println("ContentType:"+httpEntity.getContentType());//对HttpEntity操作的工具类String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);System.out.println(toStringResult);//确保流关闭EntityUtils.consume(httpEntity);}else{System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());}} catch (Exception e) {e.printStackTrace();}finally {if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}if(closeableHttpClient!=null){try {closeableHttpClient.close();} catch (IOException e) {e.printStackTrace();}}}}}

关于保存网络图片到本地:粗暴点讲就是爬取图片,再写个demo

  @Testpublic void test3(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();String userName="收到 你没";String password="阿斯顿)(";try {userName= URLEncoder.encode(userName, StandardCharsets.UTF_8.name());password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());} catch (Exception e) {e.printStackTrace();}String str="https://img-blog.csdnimg.cn/c2c20ed7275749bba0e43cdf9d66a9d7.png";//String str="http://localhost:8899/httpclient-demo/test1?userName="+userName+"&password="+password;//构造HttpGet请求对象HttpGet httpGet=new HttpGet(str);httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");//httpGet.addHeader("Referer","https://www.amamaw.com");//声明可关闭响应对象CloseableHttpResponse response = null;try {//可关闭的httpclient客户端对象执行httpGet请求response=closeableHttpClient.execute(httpGet);//代表本次请求成功或者失败的状态StatusLine statusLine=response.getStatusLine();if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等System.out.println("响应成功");//获取所有响应头Header[] allHeader=response.getAllHeaders();for(Header header:allHeader){System.out.println("响应头:"+header.getName()+":"+header.getValue());}//成功了再获取响应结果//获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体//作为响应结果的实现类是DecompressingEntityHttpEntity httpEntity=response.getEntity();//获取图片,一般图片都有后缀,如何保存为原有的后缀 image/jpg image/png image/jpeg image/图片后缀String contenType= httpEntity.getContentType().getValue();String suffix=".jpg";if(contenType.contains("jpg")||contenType.contains("jpeg")){suffix=".jpg";}else if(contenType.contains("bmp")||contenType.contains("bitmap")){suffix=".bmp";}else if(contenType.contains("png")){suffix=".png";}else if(contenType.contains("gif")){suffix=".gif";}//图片是二进制,toByteArray()可以以流的形式获取任何 文本也可以  图片  视频都行byte[] bytes=EntityUtils.toByteArray(httpEntity);
//                String str1=new String(bytes);
//                System.out.println("str1="+str1);//定义个本地保存图片的路径String localAbsPath="D:\\pachongimage\\"+new SimpleDateFormat("yyyyHHmmhhmmss").format(new Date())+suffix;//写入文件FileOutputStream fos=new FileOutputStream(localAbsPath);fos.write(bytes);fos.close();System.out.println("ContentType:"+httpEntity.getContentType());//对HttpEntity操作的工具类   注意图片是二进制文件,不能再toString()了  只有文本可以//String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);//System.out.println(toStringResult);//确保流关闭EntityUtils.consume(httpEntity);}else{System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());}} catch (Exception e) {e.printStackTrace();}finally {if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}if(closeableHttpClient!=null){try {closeableHttpClient.close();} catch (IOException e) {e.printStackTrace();}}}}}

这样该目录里就有该图片了

设置访问代理,设置访问代理原因,爬虫写多了,高频率访问网站,对方安全性做的比较好的话,会将你IP封掉.那么做爬虫的应对方式就是设置访问代理,用不同IP去访问,请求,避免被封,让它搞不清楚

设置访问代理,有免费的,但是不太稳定,要稳定加钱......

另外再写个Demo

无论HttpGet或者HttpPost都可以配置  这里用HttpGet演示   代理的IP和端口网上找的

//创建一个代理
String ip="120.26.123.95";
int port=8010;
//构造HttpGet请求对象
HttpGet httpGet=new HttpGet(str);
HttpHost proxy=new HttpHost(ip,port);
//对每一个请求进行配置,会覆盖全局的默认请求配置
RequestConfig requestConfig= RequestConfig.custom().setProxy(proxy).build();
httpGet.setConfig(requestConfig);
 /*** 演示设置访问代理*/@Testpublic void test4(){//可关闭的httpclient客户端,相当于打开一个浏览器CloseableHttpClient closeableHttpClient=HttpClients.createDefault();String str="http://www.baidu.com";//创建一个代理String ip="120.26.123.95";int port=8010;//构造HttpGet请求对象HttpGet httpGet=new HttpGet(str);HttpHost proxy=new HttpHost(ip,port);//对每一个请求进行配置,会覆盖全局的默认请求配置RequestConfig requestConfig= RequestConfig.custom().setProxy(proxy).build();httpGet.setConfig(requestConfig);//声明可关闭响应对象CloseableHttpResponse response = null;try {//可关闭的httpclient客户端对象执行httpGet请求response=closeableHttpClient.execute(httpGet);//代表本次请求成功或者失败的状态StatusLine statusLine=response.getStatusLine();if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等System.out.println("响应成功");//获取所有响应头Header[] allHeader=response.getAllHeaders();for(Header header:allHeader){System.out.println("响应头:"+header.getName()+":"+header.getValue());}//成功了再获取响应结果//获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体//作为响应结果的实现类是DecompressingEntityHttpEntity httpEntity=response.getEntity();System.out.println("ContentType:"+httpEntity.getContentType());//对HttpEntity操作的工具类   注意图片是二进制文件,不能再toString()了  只有文本可以String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);System.out.println(toStringResult);//确保流关闭EntityUtils.consume(httpEntity);}else{System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());}} catch (Exception e) {e.printStackTrace();}finally {if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}if(closeableHttpClient!=null){try {closeableHttpClient.close();} catch (IOException e) {e.printStackTrace();}}}}

关于连接超时,和读取超时的设置与具体含义

关于连接超时,也是通过RequestConfig来进行设置的,这里先把代理去掉

就是设置HTTP三次握手的时间上限,连接超时就报ConnectTimeoutException

//对每一个请求进行配置,会覆盖全局的默认请求配置
RequestConfig requestConfig= RequestConfig.custom().setConnectTimeout(5000).build();
//对每一个请求进行配置,会覆盖全局的默认请求配置
RequestConfig requestConfig= RequestConfig.custom()//设置CTP三次握手的时间上线.setConnectTimeout(55555)//设置从请求的网址获取响应数据的时间渐渐.setSocketTimeout(50000)//指从连接池获取connection的超时时间.setConnectionRequestTimeout(5000).build();
httpGet.setConfig(requestConfig);

接着演示,用HttpClient发送  

Content-Type分别为:

1.application/x-www-form-urlencoded

2.application/json

3multipart/form-data(文件上传时的Content-Type类型)

的Post请求

1.用HttpClient发送content-type为application/x-www-form-urlencoded的post请求

demo送上    注意:content-type为application/x-www-form-urlencoded

他的参数格式是在body体中:KEY1=VALUE1&KEY2=VALUE2的格式

其实下面传送过去的也就是userName=java&password=xxxx的格式

NameValuePair是个接口,BasicNameValuePair是他的一个实现类
/*** - 发送application/x-www-form-urlencoded类型的post请求** @throws Exception*/@Testpublic void testPost1() throws Exception {CloseableHttpClient closeableHttpClient = HttpClients.createDefault();String urlStr = "http://localhost:8899/httpclient-demo/test2";// 创建httppost对象HttpPost httpPost = new HttpPost(urlStr);// 设置请求头httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");// 给post对象设置参数/*NameValuePair: <input id="user-name-label" type="text" name="userName"/>的name(userName)和input标签里面输入的值就构成了一个NameValuePair对象*/List<NameValuePair> list = new ArrayList<>();list.add(new BasicNameValuePair("userName", "java"));list.add(new BasicNameValuePair("password", "xxxxx"));// 把参数集合设置到formEntityUrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);httpPost.setEntity(formEntity);CloseableHttpResponse response = null;try {response = closeableHttpClient.execute(httpPost);HttpEntity entity = response.getEntity();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 (IOException e) {e.printStackTrace();}}}}

2.用HttpClient发送content-type为application/json的post请求

在body体中的格式就是JSON

{

        "userName":"java",
        "password":"xxxx",

"age":18

}

Demo送上

  /*** - 发送application/json类型的post请求*/@Testpublic void testPost2() throws Exception {CloseableHttpClient closeableHttpClient = HttpClients.createDefault();String urlStr = "http://localhost:8899/httpclient-demo/testJson";// 创建httppost对象HttpPost httpPost = new HttpPost(urlStr);// string:是一个json字符串JSONObject jsonObj = new JSONObject();jsonObj.put("userName", "java");jsonObj.put("password", "不知道写什么");StringEntity jsonEntity = new StringEntity(jsonObj.toString(), Consts.UTF_8);// 也需要给entity设置一下内容类型
//        jsonEntity.setContentType(new BasicHeader("Content-Type","application/json; charset=utf-8"));jsonEntity.setContentType("application/json; charset=utf-8");// 设置entity的编码jsonEntity.setContentEncoding(Consts.UTF_8.name());httpPost.setEntity(jsonEntity);CloseableHttpResponse response = null;try {response = closeableHttpClient.execute(httpPost);HttpEntity entity = response.getEntity();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 (IOException e) {e.printStackTrace();}}}}

HttpClient别说话,用心看相关推荐

  1. 提升演讲与说话能力看什么书?这本《演讲与口才必读12篇》不容错过哦

    提升演讲与说话能力看什么书?演讲类书籍前前后后也看了一些,个人感觉最值得推荐的还是12Reads的<演讲与口才必读12篇>这本. (注意该书只能从其官网购买,传统电商平台无售.) 这本书最 ...

  2. 怎么用计算机弹心如水止,心静如水, 怎样用心看自己

    作者:糖糖 整理人:曹小涵 人们忙于到处奔波,为生活.为工作.为人生,很难有时间静下心思考一下,自己应该怎样看待自己?习惯了看待别人,或指指点点,或嗤之以鼻,或推崇倍至,或违心应答,但无非是给自己找一 ...

  3. 用数据说话,看Google 怎样被陷害(转自sina)

    转自新浪blog: http://blog.sina.com.cn/s/blog_60676a3f0100e0xk.html 近日,央视爆出谷歌搜索出现大量黄色词条的信息.一个引起舆论强烈反响的例子是 ...

  4. Dubbo详解,用心看这一篇文章就够了【重点】

    1.1 Dubbo概述 Dubbo是阿里巴巴开源的基于 Java 的高性能RPC(一种远程调用) 分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 每天为2千 ...

  5. Linux账号及权限管理!!!用心看!!简单易懂!!

    目录 1.用户账号 (1)超级用户 (2)普通用户 (3)程序用户 2.组账号 (1)基本组(私有组) (2)附加组(公共组) 3.标识号 (1)UID((User IDentity ,用户标识号) ...

  6. Springboot 整合RabbitMq ,用心看完这一篇就够了

    该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...

  7. PXE高效批量网络装机比较乱,用心看

    1.部署 PXE 远程安装服务 在大规模的 Linux 应用环境中,如 Web 群集.分布式计算等,服务器往往并不配备光驱设备,在这种情况下,如何为数十乃至上百台服务器裸机快速安装系统呢?传统的 US ...

  8. MongoDB详解,用心看这篇就够了【重点】

    1.1 MongoDB概述 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间 ...

  9. RabbitMQ详解,用心看完这一篇就够了【重点】

    1.1 消息中间件 消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步.可靠的消息传输的支撑性软件系统--百度百科 1.1.1 应用场景 1.1.1.1 异步处理 场景说明: 用 ...

最新文章

  1. 中科院刘焕勇老师知识图谱关于schema博客
  2. 短短30分钟!计算机轻松判断J. K. 罗琳隐姓埋名写新作
  3. mysql my.cnf key_buffer_size_mysql5.6之key_buffer_size优化设置-阿里云开发者社区
  4. ELDataQuery 基于.NET 2.0的数据查询框架 雏型
  5. java 加密服务器_Javascript端加密java服务端解密
  6. 数据结构选择题(c语言)
  7. 二级VB培训笔记05:文件操作
  8. Android系统性能优化(73)---总结
  9. java大文件读,java 读大文件报错
  10. Centos7安装完毕后无法联网的解决方法
  11. 8.1 模型压缩的方法
  12. 周志华机器学习西瓜书速记第一章绪论
  13. 部分IT公司面试流程小结
  14. 学习人工智能导论(1)
  15. 敌退我进 锂电产业链中日韩三国演义
  16. java web景点规划导航
  17. python处理wrf气象数据_气象编程 | Python3之WRF的投影转换
  18. 3类、5类、超5类线有什么不同
  19. 互联网的行业都有哪些岗位?
  20. 【总结】最好的CV学习小组,超200个课时+10个方向+30个项目,从理论到实践全部系统掌握...

热门文章

  1. 喜讯+1!袋鼠云数栈技术团队获“2022年度优秀开源技术团队”
  2. 专业演讲技巧学习笔记
  3. All in 凉凉!德州赔率怎么算?我用Python来搞定!
  4. 基于dlib进行人脸检测
  5. C语言:return 0 , return 1 和 return -1 以及 return ,break 的区别
  6. python列表去除none_从Python列表中删除None
  7. 股票量化投资目前主要有哪些主流交易方法?
  8. 叫树兄的上海行849
  9. 怎么在eclipse里复制项目
  10. 数字化转型导师坚鹏:数字化转型背景下的保险公司人力资源管理