Response - 网页
上一章我们学习了 Java
中使用 Okhttp3
库请求网页或调用 API
的知识。
使用一条语句执行调用请求,并取得返回结果字符串:
call.execute().body().string()
execute() 方法是真正执行发送请求,前面的一系列代码是做前置准备。
这段代码获得服务器返回内容的专用代码,不具备通用性,所以基于很多 大神、前辈 的编码风格,给大家展示简洁的连写风格。
其它情况下,不推荐使用连写风格。
要完全理解 body、状态码 这些知识点,可能还需要 学校 里学过 《计算机原理》 、 《计算机网络》 课程,这里不用纠结。
可以 等学校里课程学完 后再来 复习 ,这里重点是学会 完成功能 。
即使不知道水稻是如何播种、如何收获的,但不妨碍大家吃饭
实际上,除了具体的返回结果,我们通常还关心的数据是:http
状态码。
状态码是用一个数字直观反映了本次请求的状况,例如常见的 200
表示请求成功了,404
表示出错了,服务端没有被请求的内容。
具体的状态码的较多,可以参考文档,这里就不赘述了。
为了取得响应状态码,可以使用语句:
call.execute().code()
这段代码获得服务器返回内容的专用代码,不具备通用性,所以基于很多 大神、前辈 的编码风格,给大家展示简洁的连写风格。
但是通常还要读取响应内容,但是又不能执行两次请求,所以代码应该优化为:
import okhttp3.Response;
// 执行请求
Response rep = call.execute();
// 获取响应状态码
int code = rep.code();
// 获取响应内容
String content = rep.body().string();
Response - 非文本文件
之前我们学习了 Java
中使用 Okhttp3
库获取状态码及返回的文本内容。
但实际上 Okhttp3
库不仅可以请求网页、API
,也能请求图片、excel
等各种文件。
例如豆瓣首页的图片:
但我们知道,图片文件的明显不同之处在于,图片的内容不是可以直接阅读的字符文本,只是二进制编码,需要软件解析图片的二进制编码数据,才能还原成图像显示。
所以,请求图片、excel
等各种非字符文本文件时,不能使用 response.body().string()
获取返回的内容,而是要使用:
response.body().bytes();
这段代码获得服务器返回内容的专用代码,不具备通用性,所以基于很多 大神、前辈 的编码风格,给大家展示简洁的连写风格。
获取返回的二进制编码内容。
在 console 里我们看到输出:“图片 1705022 字节”,约 1.6 mb
。
在以后的章节中,我们会学习把请求的图片写入到图片文件中,这样可以通过浏览器等工具查看图片。本章就不赘述了。
关于二进制与字节,属于计算机的基础知识,不熟悉的同学可以看点击扩展阅读
Response - JSON
之前,我们学习了 Java
中使用 Okhttp3
库获取请求返回的内容。无论是文本文件,还是二进制文件,都能够熟练使用了。
而在工作中,经常会调用 API
,而很多 API
返回的文本内容是 JSON
格式的。
JSON
是一段文本,也就是 Java
的字符串,是难以进行解析具体内容的。必须转换成 Java
的对象。
之前我们已经学习过使用 fastjson
库把参数对象转换为 JSON
格式字符串,当然也可以把 JSON
结果转换为对象,方便程序今后一步分析。
JSON.parseObject()
附录
这节课我们用到了 JSON。对 JSON 及其使用不熟悉的同学,可以点击《JSON 与 FastJSON》文档
解析JSON对象
之前学习了如何查询 API
,获取 JSON
结构的结果。
实际工作中,对于返回值为 JSON
格式的 API
,我们不仅要学习如何调用 API
,更重要的是如何解析调用结果。
例如上节课的代码演示,通过查询 IP
地址信息的结果是:
{
"status": "success",
"country": "China",
"countryCode": "CN",
"region": "ZJ",
"regionName": "Zhejiang",
"city": "Hangzhou",
"zip": "",
"lat": 30.294,
"lon": 120.1619,
"timezone": "Asia/Shanghai",
"isp": "Chinanet",
"org": "Chinanet ZJ",
"as": "AS4134 Chinanet",
"query": "115.227.217.8"
}
如果是更复杂的多次嵌套结构的 JSON
数据:
{
"code": 0,
"data": {
"ip": "117.89.35.58",
"country": "中国",
"area": "",
"region": "江苏",
"city": "南京",
"county": "XX",
"isp": "电信",
"country_id": "CN",
"area_id": "",
"region_id": "320000",
"city_id": "320100",
"county_id": "xx",
"isp_id": "100017"
}
}
只需要多次取出嵌套的 Map
对象即可:
Map contentObj = JSON.parseObject(content, Map.class);
Map dataObj = (Map)contentObj.get("data");
String city = (String)dataObj.get("city");
因为 Map
可以存储任何对象,所以从 Map
中 get()
到的对象必须指定其实际的类型:(Map)
、(String)