Java网络编程——简单的 API 调用

Get请求 - 无参数

上一章我们学习了网络的基本概念,我们知道 URL 能输入到浏览器地址栏中被打开,

那么能不能在程序中发送请求,获取结果呢?

img

例如“中国科学技术大学”的网站(https://www.ustc.edu.cn/):

网站

Java 功能非常强大,用来实现抓取网站内容也非常简便。那么是如何实现它的呢?

安装依赖库

首先,我们需要安装一个库: Okhttp3,这是一个非常流行的 HTTP 库,可以简单、快速的实现 HTTP 调用。

安装 Okhttp3 的方式是在 pom.xml 文件中增加依赖:

<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
 <groupId>com.squareup.okhttp3</groupId>
 <artifactId>okhttp</artifactId>
 <version>4.1.0</version>
</dependency>

唯一<dependencies> 标签中,包含多个 <dependency> 标签,每一个 <dependency> 标签表示一个依赖库。书写时注意嵌套顺序哦。

pom.xml 文件的作用就是定义 Java 项目需要用到(或者说依赖到)哪些库。

不必纠结 pom.xml 的含义及原理,在以后的高阶课程里会详细讲。当前会写依赖标签即可。

使用详解

使用 Okhttp3 完成页面请求,需要三大步骤:

  1. 实例化 OkHttpClient。使用 OkHttpClient okHttpClient = new OkHttpClient(); 代码。
  2. 执行调用。
    1. 在执行调用之前,需要实例化一个 Request 对象,作用是定义请求的各种参数,Request request = new Request.Builder().url(url).build();
    2. 然后构建调用对象 Call call = okHttpClient.newCall(request);
    3. 最后执行调用,如果调用失败可能抛异常,所以必须抓取异常。call.execute() 就是执行调用的代码。
  3. call.execute() 返回的其实是一个执行的结果对象,调用对象的方法即可获取返回的字符串内容:call.execute().body().string();

这个过程你可以类比打电话:

  • 拿出手机,相当于实例化Request对象,
  • 拨号,相当于newCall()方法,这些都是前置操作,
  • 每说一句话,相当于执行 execute() 方法,
  • 听到对方说的话,就相当于获取返回结果 body().string()

演示的代码基本上都属于固定写法

任何时候都不要忘记 pom.xml 文件添加依赖,以及代码中使用 import 语句引入使用的类哦。

由于 Java 一切皆对象的理念,所以实际上代码量可能比大家想象的要大。

但是没关系,我们把调用的步骤封装在一个 getContent() 方法中,比较容易理解,也方便复用。大家不用太纠结,主要目标是熟练写出完整的代码。

关于输出结果

call.execute().body().string(); 可以取得服务器返回的具体内容。在下一章我们会详细学习,这里大家知道用法即可。

我们在 console 中看到的大量的文本内容,这是给浏览器识别的内容,包含了很多无效的内容。所以很多时候,我们使用程序调用 API,获取到需要的数据。

什么是 API

API 全称 Application Programming Interface,应用程序接口,API 一般是指一些预先定义的函数,目的是可以为开发人员快速访问某一程序,而无需了解和访问源码,或理解它内部工作机制的细节。

简单的讲,API 可以快速调用某个程序

这在计算机里叫做接口,我们生活中也有很多接口,比如 U 盘可以储存信息,我们访问 U 盘,只需要把 U 盘插到电脑上就可以访问,插入的 USB 接口就是一个接口,我们不需要关心它是如何实现的。

又比如电视机上有很多接口,有的连话筒,有的连视频,我们只需要直接插上对应的线就可以实现相应的功能,并不关心它的具体机制。

如果大家想要了解关于更多 API 的知识,可以点击查看这个文档

调用 API

我们看一个查询 杭州市 天气的 API

https://api.seniverse.com/v3/weather/daily.json?key=SCYrvkytJze9qyzOh&location=杭州

把这个 URL 贴到浏览器,可以看到查询返回结果为:

{"results":[{"location":{"id":"WTMKQ069CCJ7","name":"杭州","country":"CN","path":"杭州,杭州,浙江,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[{"date":"2023-05-09","text_day":"晴","code_day":"0","text_night":"晴","code_night":"1","high":"20","low":"10","rainfall":"0.00","precip":"0.00","wind_direction":"东","wind_direction_degree":"90","wind_speed":"23.4","wind_scale":"4","humidity":"69"},{"date":"2023-05-10","text_day":"阴","code_day":"9","text_night":"小雨","code_night":"13","high":"22","low":"12","rainfall":"5.40","precip":"0.88","wind_direction":"东","wind_direction_degree":"90","wind_speed":"32.8","wind_scale":"5","humidity":"75"},{"date":"2023-05-11","text_day":"小雨","code_day":"13","text_night":"阴","code_night":"9","high":"20","low":"15","rainfall":"0.43","precip":"0.41","wind_direction":"无持续风向","wind_direction_degree":"","wind_speed":"3.0","wind_scale":"1","humidity":"80"}],"last_update":"2023-05-09T08:00:00+08:00"}]}

这一大段的内容,跟常见的精美的网页不同,全是数据,看到有些眼花缭乱。仔细看还是能看到 2023-05-09 杭州 的天气是

数据基本上不是让人直接阅读的,是给前端程序使用的

关于前端编程在下一个阶段学到,目前不要纠结

所谓 API,本质上就是一个 URL。开头也是 http(或https),与精美的网页相比,内容有明显的区别。

API 返回的内容统称为数据,关于数据的格式,我们以后会逐步讲到,这里先不赘述。

接下来我们就来动手实践吧!

网络编程的学习方法

学完本章,大家可能会有很多的疑问,特别是诸多代码看不懂。

这是 正常 的。

首先,网络编程与前面课程中的程序最大的不同,是用到了新的 程序开发包

这种程序开发包,由于不是 Java 官方出品的,而是其他公司或个人 开源 的,通常也叫 二方包

程序开发包,是为了更加简便的完成某些特定的功能,提升开发效率。

如果不用 Okhttp3 ,而是用 JDK 内置的类,也能完成相同的功能,但代码量会大很多。上一节 getContent() 方法大约有 18 行,如果不用 Okhttp3 代码量可能要再增加 3-4 倍。

除了第一次接触 Okhttp3 不习惯外,还有一个原因是大家对计算机的基础理论知识不熟悉,所以 Requestbody() 这些都感觉懵懵懂懂。

计算机的基础理论知识,包括“计算机原理”、“计算机操作系统”、“计算机网络”等学校里的专业课程。这些课程学完以后,才能对本课程中涉及的代码有比较好的理解。

计算机网络的基础理论知识一般计算机专业会教,不是计算机专业的同学必须自学

不熟悉计算机网络知识就无法编程了吗?

答案是否定的: 当然可以编程

我们上节课已经用程序抓取了网页的源码和 API 的数据内容呢。

需要改变学习方法

学习开源技术的方法,与学习其它知识的方法,略有不同。

例如 Okhttp3 程序开发包的使用,我们可以先从粗到细的学习。就是说,我们 首先 要清晰的知道,这个技术解决了什么问题。

做什么

学过本课程,我们再看到一个新的 网址 ,必须能够想到使用 Okhttp3 获取其内容。

新网址无论是网页还是 API ,都要能举一反三,都能想到可以用 Okhttp3

怎么做

在第一节课中,已经把抓取过程的代码,封装在一个方法中:

public String getContent(String url) {
}

调用这个方法很简单,只要在参数中输入想抓取的网址,就会返回抓取的内容。

学习重点

记住:调用 getContent() 方法,即可抓取到网址的内容。就是说,首先要了解的是:知道什么代码可以解决什么问题、完成什么功能。

如果 getContent() 方法内的代码,某些细节看不懂,也 不要纠结 。因为,编程与考试不同的是,开发编程是允许查资料的。

就像我们都是先学会吃饭,即使不懂播种、打谷,也可以填饱肚子。

各位同学自己把完整的 getContent() 方法代码记在电脑上,例如印象笔记等各种笔记软件,甚至手写在纸质笔记本上,都可以。需要用的时候 copy 出来,即可完成功能。

当然,不要忘了两个配套步骤:添加依赖,不要遗漏 import 语句。

后面的章节

接下来的章节,根据不同的场景和条件,getContent() 方法的实现代码又会有一些不同。

那么大家学习后面的章节,就要特别注意区分,不同的代码适用于什么场景、能解决什么问题。

未来持续学习

待自己补充了计算机网络的理论知识,加上编程达到熟练程序以后,就可以回过头来研究 Okhttp3 的代码细节啦。

先预览一下 Okhttp3 的源代码:

img

现在看觉得很难,看不懂,没关系,随着技术能力的成长,以后会看得懂的。

我们目前要做的,是优化学习方法,分清主次、 抓重点

Get请求 - 有参数

上面我们练习了如何在程序中调用 API 获取结果。 很多情况下,API 调用需要参数,

例如,下列查询 IP 地址信息的 API

http://ip-api.com/json/?lang=zh-CN

我们只要把包含参数的完整的 URL 直接传入到方法中就可以了。

如果对 URL 的格式不熟悉,需要复习本课程第一章第二节哦

本节课没有新的知识点,希望大家强化编程训练,在编程的过程中加深理解 URLAPI

POST表单数据

我们先来看一个故事:

话说灵剑派新弟子招募大会升仙大会在灵剑山下的灵溪镇召开,王陆跃跃欲试,也来到灵溪镇。镇上只有一家如家客栈,如果住不进去,就只能露宿街头了。
王陆来到如家客栈门口,只见一群人围在客栈门口,王陆很好奇,这是怎么回事呢?
此时老板娘来到客栈门前,开口说道:欲入住咱们如家客栈,除了需要登记姓名、年龄、籍贯外,最重要的,是必须持有准入券,请持有准入券者入内登记吧。
王陆微微一笑,嗖的一声从怀里掏出一张长方形纸片,只见白底绿纹上三个大字:准入券,字上鲜红大印格外醒目。老板娘接过准入券笑吟吟做个手势:客官请。

提交数据至服务端进行增加、修改、删除等操作,都是 POST 操作。与王陆登记入住客栈类似,我们在网页上提交表单进行登录的场景,就是典型的 POST 操作。

URL格式

现在,我们回到计算机的世界,Java 是如何实现 POST 操作的呢?

post() 方法

Okhttp3 库也支持 POST 操作。我们前面学习的调用 API 属于 GET 操作。不同的是,POST 操作时,数据不是放在 URL 中的,而是放在表单中提交的。

所以程序实现需要构建一个 FormBody 表单对象,用于放置表单数据。核心代码如下:

Builder builder = new FormBody.Builder();
// 设置数据,第一个参数是数据名,第二个参数是数据值
builder.add("", "");
FormBody formBody = builder.build();

Request request = new Request.Builder().url(url).post(formBody).build();

数据的写法是不是很眼熟呢?整体步骤跟请求 API 相似,不同的是,在构建 Request 对象时,使用 .post(formBody) 语句放入表单对象,就表示执行 POST 操作啦。

这段代码仍然属于固定写法,这里要学会熟练使用。

连写代码

这段代码出现了连写。

new Request.Builder().url(url).post(formBody).build();

大多数情况下 不推荐 使用连写(特别是新手不要使用连写)的方式。不用连写的方式应该写作:

Request.Builder build = new Request.Builder();
build = build.url(url);
build = build.addHeader("Referer", "http://www.taobao.com");
build = build.post(formBody);
Request request = build.build();

Request.Builder 表示 Builder 是 Request 的内部类。特殊的是需要通过 Request 类引用 Builder 类。

不懂内部类也没关系,不用纠结,重点是知道这段代码的功能就可以了。

关于内部类的知识点可以找 Java 书籍学习。

要完全理解 url header post 这些知识点,可能还需要 学校 里学过 《计算机原理》《计算机网络》 课程,这里不用纠结。

可以 等学校里课程学完 后再来 复习 ,这里重点是学会 完成功能

即使不知道水稻是如何播种、如何收获的,但不妨碍大家吃饭

不连写的代码可能对新手更友好一点。但这段代码是发送 POST 请求专用的代码,不具备通用性,所以基于很多 大神前辈 的编码风格,给大家展示简洁的连写风格。

请看下列代码演示 POST 登录的过程:

我们仍然把发送表单数据的过程,封装为 postConten

POST JSON 数据

在日常开发工作中,除了提交表单数据以外,也经常用到提交 JSON 数据。

跟表单数据提交方法一样,也是调用 post() 方法,只是参数不再使用 FormBody 对象,而是使用 RequestBody

示例

下列程序演示用 JSON 方法提交数据,注册一个新用户,数据包括:

数据名数据值
name张飞
secondName翼德

从 console 打印结果可以看到,服务器注册成功,并生了新用户的 id 号。

详解

实现 JSON 方式提交数据的步骤:

  1. 将数据转换成 JSON 格式的字符串,调用 JSON.toJSONString() 方法即可。
  2. 创建 RequestBody 实例,注意需要指定提交的类型是 application/json; charset=utf-8 。这里的 utf-8API 规定的编码格式。此例子中,API 规定数据传输的编码格式是 utf-8 - 编码属于另一个比较长的话题,属于课外知识了,有兴趣的同学可以看一下 码表的理解(ASCII,GBK,Unicode,UTF-8 等)
  3. 构建 Request 实例对象时,调用 .post(requestBody) 即表示使用 JSON 的方式提交数据。

这些基本上都是固定写法,大家需要熟练应用。

附录

这篇我们用到了 JSON。对 JSON 及其使用不熟悉的同学,可以点击《JSON 与 FastJSON》文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值