前言

HTTP(Hyper-Text Transfer Protocol,超文本传输协议)在如今的互联网也许是最重要的协议,我们每天做的很多事情都与之有关,比如,网上购物、刷博客、看新闻等。偶尔你的上级还会安排任务给你让你去对接API接口(RESTFUL),你接到任务后,啪啪的敲了一行又一行代码,一遍敲着一遍心里骂着:这是谁设计的这样脑残接口,一点都不好用,对接起来非常麻烦,最终,你怀着极其复杂的心情把api对接完了。有一天你的上级叫你去开发一个API接口,你情绪高涨,把接口开发完了,结果......。在程序中使用RESTFUL API,与传统的webservice相比,耦合度更低,任何能使用http的地方都能使用RESTFUL API,你能在java、python中调用,甚至能在网页中使用ajax来调用。

HttpClient是Apache HttpComponents的一个组件,提供了用来发送HTTP请求和接受HTTP响应的组件库,它并不是一个浏览器,但是他实现了浏览器HTTP相关的功能。你能使用HttpClient来构建你所需要的应用,例如:网页爬虫、调用RESTFUL接口等。JDK提供的HttpURLConnection也支持HTTP特性,不过使用起来比较麻烦,为了能写入请求体和读取请求体,你不得不分别获取底层的InputStream和Outputstream,在流的角度上来进行操作。HttpClient使得这种操作非常简单,而且非常灵活易于扩展。为了增强趣味性,本文就HttpClient的一些较简单的实战,从两个例子开始来说明HttpClient API的使用。

环境准备

  • 本文使用的是JDK8,请确保安装了JDK8或者更高版本的JDK。
  • 为了能使用HttpClient,需要在maven中添加如下的依赖:
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.6</version>
</dependency>
  • 在示例一中使用了jackson来解析JSON,需要加入如下的依赖包:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.6</version>
</dependency>
  • 在示例二中使用了jsoup来解析html文档,需要加入如下的依赖包:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>1.11.3</version>
</dependency>
  • 如果想要有日志输出则还需要添加log4j的日志依赖包,本文使用的是log4j2:
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.11.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.11.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-jcl</artifactId><version>2.11.0</version>
</dependency>

例子1:从阿里云API接口获取天气预报信息

在java程序中调用第三方厂商提供的API接口是很常见的需求,假设要写一个程序,根据传入的城市名称来展示该城市当天的天气信息。当然要自己动手去测量天气信息,这应该不是一件简单的事情,但是我们可以借助其他的接口来查询天气信息。阿里云上的全国天气预报查询接口就挺好用的,而且还是免费的(不过限制只能调用一万次)。你首先需要购买该api接口,购买完成后,会得到一个appCode,有了这个appCode,你可以在上面在线调试该接口。博主自己已经购买了,各位可以使用博主的这个appCode。

public class WeatherQuery {static String appCode = "4073983cf899411a8792dec11dc88e43";static String url = "http://jisutqybmf.market.alicloudapi.com/weather/query";public static void main(String[] args) throws Exception {if (args.length != 1) {System.err.println("Usage: <city name>");System.exit(-1);}String charset = "utf-8";String encodedCityName = URLEncoder.encode(args[0], charset); // 获取参数,并进行编码CloseableHttpClient client = HttpClients.createDefault(); // 创建一个Http客户端try {HttpGet httpget = new HttpGet(url + "?city=" + encodedCityName);// add Authorized Headerhttpget.addHeader(new BasicHeader("Authorization", "APPCODE " + appCode)); // 设置认证头信息System.out.println("Executing request: " + httpget.getRequestLine());CloseableHttpResponse response = client.execute(httpget); // 执行请求,返回响应try {System.out.println("-----------------------------------------");System.out.println(response.getStatusLine());String content = EntityUtils.toString(response.getEntity(), charset); // 将请求体转出字符串System.out.println("Response: " + content);Map<String, ?> map = parseJson(content); // 将请求回到到的JSON字符串转换成MapMap<String, ?> weatherData = (Map<String, ?>) map.get("result"); // 获取天气信息// 打印天气信息System.out.printf("%s  %s%n", weatherData.get("date"), weatherData.get("week"));System.out.printf("%s  %s  %s~%s℃    %s%s", weatherData.get("city"),  weatherData.get("weather"), weatherData.get("templow"), weatherData.get("temphigh"), weatherData.get("winddirect"), weatherData.get("windpower"));} finally {response.close();}} finally {client.close();}}static Map<String, ?> parseJson(String content) throws Exception {ObjectMapper objectMapper = new ObjectMapper();return objectMapper.readValue(content, Map.class);}
}

首先创建了一个HttpClient的实例,用来执行请求操作,创建了HttpGet的实例表示要发送的是GET请求,并在请求头中加入了app认证信息:httpget.addHeader(new BasicHeader("Authorization", "APPCODE " + appCode))response.getEntity()获取响应体信息,调用EntityUtils.toString工具类,将该响应体转换成字符串,接下来用Jackson解析返回的响应的JSON信息,用printf将获取到的天气信息输出到控制台。注意:要在try finally中关闭HttpClient和Response,以完成资源的释放。

执行命令来测试:% WeatherQuery 广州,产生了如下的输出:

2018-07-19  星期四
广州  多云  27~33℃    西南风1级

例子2:获取博客园精华文章

对爬取到的html进行解析是爬虫程序很关键的一环,接下来,看一下简单的html内容分析的例子:爬墙博客园首页的精华文章信息。和例一类似,首先需要创建一个HttpClient的思路,然后创建一个GET请求,执行请求获取响应体信息。为了能提取出精华文章信息,调用Jsoup.parse方法,该方法返回Document对象,调用该对象上的select,并传入CSS选择器相关的方法,选择出我们要提取的内容。

public class CnblogsPickFetch {static String url = "https://www.cnblogs.com/pick/";public static void main(String[] args) throws Exception {CloseableHttpClient client = HttpClients.createDefault();try {HttpGet httpget = new HttpGet(url);System.out.println("Executing request: " + httpget.getRequestLine());CloseableHttpResponse response = client.execute(httpget);try {System.out.println("-----------------------------------------");System.out.println(response.getStatusLine());String content = EntityUtils.toString(response.getEntity(), "gbk");Document doc = Jsoup.parse(content); // 将获取到的html文档进行解析Elements postItems = doc.select("#post_list .post_item"); // 选择精华文章列表System.out.printf("%-9s\t%-24s\t%s%n", "推荐数", "作者", "标题");System.out.println("-----------------------------------------------------");for (Element postItem : postItems) {String diggit = postItem.select(".diggit").text(); // 获取推荐数String title = postItem.select(".post_item_body .titlelnk").text(); // 获取文章标题String author = postItem.select(".post_item_foot .lightblue").text(); // 获取文章作者System.out.printf("%-6s\t%-24s\t%s%n", diggit, author, title);}} finally {response.close();}} finally {client.close();}}}

运行该程序得到的结果如下(省略掉了部分结果):

推荐数         作者                          标题
-----------------------------------------------------
334     小曾看世界                       通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
109     陈树义                         藏在正则表达式里的陷阱
16      程序诗人                        你所不知道的日志异步落库

总结

本文通过两个简单的例子来说明了HttpClient的用法,当然这只是HttpClient的冰山一角,本文也不旨在全面较深入的介绍HttpClient,其更加高级的用法将在陆续的文章中进行介绍。来,总结下HttpClient的基本流程:

  1. 创建一个HttpClient的实例;
  2. HttpGet、HttpPost或者其他类似的请求对象,并设置请求头、请求体信息;
  3. 执行请求并返回Response的实例;
  4. 处理响应消息。

相关资源

  • 本文例子源码下载
  • HttpClient官网
  • 阿里云天气API购买地址

转载于:https://www.cnblogs.com/zhangfengxian/p/learning-httpclient-from-two-examples.html

学习HttpClient,从两个小例子开始相关推荐

  1. C两个小例子(数组与指针)

    大端模式 所谓的大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放: 例子: ...

  2. 用两个小例子来解释单例模式中的“双重锁定”

    学习单例模式时,好多人都不太理解双重锁定.学完后突然想到一个很有趣的例子. 单例模式结构图: 代码: Singleton类 class Singleton{private static Singlet ...

  3. 通过两个小例子,更快了解-Xms -Xmx

    我们偶尔就会遇到OutOfMemoryError,面试的时候总是能够被问道,可明明背好的面试题临时又不会了,答出来也很生硬,自己都想让自己快点"回家等通知",那我们就通过下面的两个 ...

  4. MonoRail学习笔记一:一个小例子

    随着微软放出消息,准备发布MVC的框架,各种议论纷至沓来. 以前用java.jsp对它的MVC结构.集中控制印象特别深刻,自从用了.NET后,虽然webform的控件很好用,总感觉有点怪怪的 在网上搜 ...

  5. 微信小程序学习笔记(三)——两名片小程序实例

    文章目录 项目一 项目结构 title index.wxml index.wxss 最终效果 项目二 项目结构 title index.wxml index.wxss 最终效果 项目地址 最后 项目一 ...

  6. Kaldi 实战学习(1)说话人识别小例子(egs/aishell/v1)

    代码 进入:~/kaldi/egs/aishell/v1 # 地址变量(引号可省略,但是=之间不可有空格!) data=/export/a05/xna/data data_url=www.opensl ...

  7. OpenResty学习中的几个小例子汇总

    1.测试lua或是LuaJIT的版本号 如果使用的是标准 Lua,访问 /lua-version 应当返回响应体 Lua 5.1 如果是 LuaJIT 则应当返回类似 LuaJIT 2.0.2 这样的 ...

  8. 【学习备份】ajax添加小例子

    实现目的:保存模板编号.模板名称到数据库 1.js引用 <script src="../../../../../../../js/jquery-1.10.2.min.js"& ...

  9. 在Android初次的前期学习中的二个小例子(2)

    Hello13:SQLite数据库 一.简述SQLite的概念和主要特性 SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,使用非常方便,支持SQL语法标准和数据库事务原则. 相对于Sh ...

最新文章

  1. servlet-------------jsp 地址栏变化
  2. 装了BT5后要做的几件事
  3. 判断字典中指定key是否存在
  4. 函数声明指令(stdcall, cdecl,pascal,register)
  5. 注册表被黑客篡改 怎样修复_使用快速注册表黑客设置Office 2007配色方案
  6. mysql 权重 取值_mysql如何按权重查询数据啊?
  7. MFC CStringArray 字符串数组类 使用方法
  8. oracle 两表两列数据对比_【SQL】根据两列信息,整合两张表数据
  9. 360浏览器html5无法播放,win7系统360浏览器播放不了视频的解决方法
  10. vue 浏览器页面刷新
  11. 推荐三款实用的录音转文字软件给你
  12. POI读取Excel(兼容Excel2003、Excel2007)
  13. 华为鸿蒙harmonyos-面向全场,华为鸿蒙 OS 下月发布?别做梦了……
  14. pytorch中tf.nn.functional.softmax(x,dim = -1)对参数dim的理解
  15. 利用vue-pdf插件来让pdf的base64数据显示在页面上
  16. 华为电脑可以升级鸿蒙系统吗,华为电脑现在是鸿蒙系统吗_华为p40升级鸿蒙系统...
  17. ZUCC_BB平台-Quiz B-3-7-答案
  18. 论文笔记-Integration of AI activities in software development processes
  19. 小米2S最新Android版本,小米2/2s如何刷Android 5.0?小米2s升级安卓5.0步骤
  20. 面试官:反射都不会,还敢说自己会Java?

热门文章

  1. nodejs 前端 返回数组给_互联网寒冬,一年经验字节跳动、虾皮、快手、拼多多前端面试总结...
  2. cad显示驱动程序文件已丢失或损坏_win7系统下打开AutoCAD 2014时显示驱动程序文件.hdi丢失如何解决...
  3. jquery 查找表格里的input_jquery获取input表单值的代码
  4. SpringBoot POM 热部署(spring-boot-devtools)
  5. flask response响应
  6. nginx ngx_http_access_module
  7. Java SSM 与 SpringBoot
  8. C语言字符型char和整型int的关系和示例
  9. Linux bond6配置文件,Linux网卡bond
  10. vSAN 监测失败并显示错误:“未能生成 HTML 包:Gem::Package::TooLongFileName: (Failed to generate HTML bundle: Gem::Pac