1. 引言
如今几乎任何现代应用都会使用来自互联网的数据。当你在手机上查看天气、叫车或阅读新闻时——这背后都是在使用API。程序彼此“对话”、交换消息,而这些消息通常就是简单文本——JSON 格式。
JSON(JavaScript Object Notation)已成为服务之间交换数据的标准。程序员和机器都喜欢它:人能轻松读懂文本,程序也能轻松解析。JSON 只有几条规则:
- 数据可以存储为对象/字典 { "key": 值 },
- 也可以是数组 [值1, 值2],
- 或者是简单的字符串、数字、布尔值以及 null。
例如,下面是一个描述人的 JSON 对象:
{
"name": "Alice",
"age": 25,
"skills": ["Java", "Python", "SQL"]
}
我们看到键(name、age、skills)及其对应的值。紧凑、直观且通用。
2. 认识 API
API(Application Programming Interface)是一个“协议”或“契约”,它说明:如果你按某个特定的互联网地址访问并提供指定参数,我会按约定格式返回响应。
用于获取数据的地址称为 endpoint。它就是一个 URL。URL 中经常会带上请求参数——也就是所谓的查询参数。
例如,这样的 URL 会返回明斯克的天气预报:
https://api.open-meteo.com/v1/forecast?latitude=50.45&longitude=30.52¤t_weather=true
仔细观察,问号 ? 之后列出了参数:
- latitude = 50.45 — 纬度,
- longitude = 30.52 — 经度,
- current_weather = true — 请求当前天气。
某些 API 还需要特殊的“密码”——API 密钥。这时把它加到参数中,例如 & apikey = YOUR_KEY。
可以在 open-meteo.com 网站查看该天气服务的文档。
3. API 的响应长什么样?
当我们发出请求时,服务器会以文本形式响应我们:一段 JSON 字符串。有时是 JSON 对象,有时是 JSON 数组。
天气响应示例:
{
"latitude": 50.45,
"longitude": 30.52,
"current_weather": {
"temperature": 21.3,
"windspeed": 5.2,
"weathercode": 1
}
}
返回 ISS 坐标的服务示例响应:
{
"timestamp": 1717590000,
"iss_position": {
"latitude": "48.1234",
"longitude": "12.5678"
},
"message": "success"
}
4. 示例一:获取天气
我们来写一小段代码,调用免费的天气 API open-meteo.com,并把响应直接打印到控制台。
String url = "https://api.open-meteo.com/v1/forecast?latitude=50.45&longitude=30.52¤t_weather=true";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("HTTP 状态: " + resp.statusCode());
System.out.println("服务器响应:");
System.out.println(resp.body());
这里我们:
- 创建 HttpClient 客户端。
- 构造 GET 请求(HttpRequest)。
- 发送请求:client.send。
- 以字符串形式获取响应:HttpResponse<String>。
如果一切正常,你会看到 HTTP 状态 200 和包含天气的 JSON。
5. 示例二:追踪 ISS
现在调用 open-notify.org 的 API,它会实时显示国际空间站(ISS)的坐标。
String url = "http://api.open-notify.org/iss-now.json";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
结果看起来会是这样:
{
"timestamp": 1717590000,
"iss_position": {
"latitude": "48.1234",
"longitude": "12.5678"
},
"message": "success"
}
此刻你拿到的是在地球上空飞行的空间站的精确坐标。如果一分钟后再次运行这段代码——数值就会不同。
6. 一些有用的细节
开始使用 API 时,有几件事非常重要。
首先,务必查看响应状态:resp.statusCode()。如果是 200 —— 一切正常。若是 404 —— 地址不正确。若是 401 —— 需要密钥。若是 429 —— 请求过多。
其次,要记住限流/配额。免费的服务会限制请求频率,以免有人把服务器压垮。
第三,JSON 并不总是“美观”。有时它是一整行的长字符串——这很正常。稍后我们会学习引入库(Jackson、Gson),把 JSON “解析”为字段,并像对象一样与之交互。
再做一个小实验
试用一个返回猫咪随机趣闻的 API:
String url = "https://catfact.ninja/fact";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
多次运行这段代码,每次都会得到一个包含某条趣闻的新 JSON。
GO TO FULL VERSION