Java 中的 Http 客户端 API:基础知识
概述
Java 11 中引入了新的 HttpClient API。它是不适合 HTTP 协议的旧 HttpURLConnection API 的替代品。这个新的 API 使用构建器模式和流畅的 API 来创建通过网络进行通信所需的对象。它还提供以下功能:
- 支持HTTP2协议。
- SSL 加密。
- 同步和异步通信模型。
- 支持 HTTP 方法。
- 身份验证机制(基本)。
- 饼干。
API 包含三个主要类:
HttClient 用于通过网络发送多个请求并接收响应。
HttpRequest 是一个不可变的类,表示要发送的 http 请求。它可以配置为特定的 HTTP 方法并附加正文(如果有)。
HttpResponse 描述来自 Web 服务器的响应。当提交请求时,它由 HttpClient 返回。如果调用是异步的,它将返回一个 CompletableFuture。
步骤很简单。首先,创建 HttpClient 的实例,然后调度 HTTP 请求。最后,请求被传递到 HttpClient 发送方法,并返回响应对象(如果调用是异步的,则返回 CompletableFuture)。
实际用例
事不宜迟,让我们看一些例子:
对于此演示,SpringBoot REST 应用程序将公开一个端点(位于http://localhost:8080/api/v1/customers)
,允许列出/添加/更新/删除客户。Customer 只是一个具有一些成员的不可变 POJO 类。借助 HttpClient API,我们将在与服务交互时执行 CRUD 操作。
1. 获取客户列表
第一个场景是获取所有客户的列表。这只是对客户资源 URL 的 GET 请求。
HttpClient client = HttpClient
.newBuilder()
.connectTimeout(Duration.ofMillis(500))
.build();
请注意,如果半秒内未建立连接,则会超时。接下来是 http 请求对象。
HttpRequests request = HttpRequest
.newBuilder()
.uri(URI.create("http://localhost:8080/api/v1/customers"))
.header("Content-Type", "application/json")
.GET()
.build();
现在通信可以同步完成,也就是说,执行被阻塞,直到收到响应。
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.printf("Status %s \n", response.statusCode());
System.out.printf("Response %s \n", response.body());
BodyHandlers 类包含将响应正文数据转换为 Java 对象(如字符串)的便捷方法。
程序输出
Status 200
Response [
{"id":1,"name":"Joe Smith","email":"joe.smith@gmail.com","dateOfBirth":"2008-01-01"},
{"id":2,"name":"Robert Moody","email":"robert.moody@gmail.com","dateOfBirth":"1985-06-21"},
{"id":3,"name":"Jennifer Dolan","email":"jennifer.dolan@gmail.com","dateOfBirth":"1966-11-11"},
{"id":4,"name":"Christopher Farrel","email":"christopher.farrel@gmail.com","dateOfBirth":"1970-04-15"},
{"id":5,"name":"Caroline Red","email":"caroline.red@gmail.com","dateOfBirth":"1992-03-05"}
]
我们可以通过调用 sendAsynch 方法异步发送相同的请求。此调用是非阻塞的,它将
立即返回一个 CompletableFuture。
CompletableFuture<HttpResponse<String>> responseFuture = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
responseFuture
.thenApply(HttpResponse::body)
.thenApply(String::toUpperCase)
.thenAccept(System.out::println)
.join();
在上面的管道中,从响应中提取正文,将其大写并打印。
程序输出
[
{"ID":1,"NAME":"JOE SMITH","EMAIL":"JOE.SMITH@GMAIL.COM","DATEOFBIRTH":"2008-01-01"},
{"ID":2,"NAME":"ROBERT MOODY","EMAIL":"ROBERT.MOODY@GMAIL.COM","DATEOFBIRTH":"1985-06-21"},
{"ID":3,"NAME":"JENNIFER DOLAN","EMAIL":"JENNIFER.DOLAN@GMAIL.COM","DATEOFBIRTH":"1966-11-11"},
{"ID":4,"NAME":"CHRISTOPHER FARREL","EMAIL":"CHRISTOPHER.FARREL@GMAIL.COM","DATEOFBIRTH":"1970-04-15"},
{"ID":5,"NAME":"CAROLINE RED","EMAIL":"CAROLINE.RED@GMAIL.COM","DATEOFBIRTH":"1992-03-05"}
]
2. 创建新客户
POST 方法将用于创建新客户。正文必须填充 JSON 格式的客户数据。BodyPublishers 类提供了方便的方法,将 java 对象转换为数据流,以便作为请求正文发送。
HttpRequest request = HttpRequest
.newBuilder()
.uri(URI.create("http://localhost:8080/api/v1/customers"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"name\":\"Sonia Lamar\",\"email\":\"sonia.lamar@mail.com\",\"dateOfBirth\":\"1998-07-29\"}"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.printf("Status %s \n", response.statusCode());
System.out.printf("Location %s \n", response.headers().map().get("location"));
程序输出
Status 201
Location [http://localhost:8080/api/v1/customers/6]
3. 更新新客户
PUT 方法将用于完全替换现有客户。这意味着除 id 之外的所有字段都将被更改。对于部分更新,例如仅更新电子邮件,PATCH 方法更合适。
HttpRequest request = HttpRequest
.newBuilder()
.uri(URI.create("http://localhost:8080/api/v1/customers/4"))
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString("{\"name\":\"Victor Martin\",\"email\":\"victor.martin@mail.com\",\"dateOfBirth\":\"1977-04-15\"}"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.printf("Status %s \n", response.statusCode());
System.out.printf("Body %s \n", response.body());
程序输出
Status 200
Body {"id":4,"name":"Victor Martin","email":"victor.martin@mail.com","dateOfBirth":"1977-04-15"}
4. 删除新客户
最后的场景是删除 id 为 3 的客户。
var request = HttpRequest
.newBuilder()
.uri(URI.create("http://localhost:8080/api/v1/customers/3"))
.header("Content-Type", "application/json")
.DELETE()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.printf("Status %s \n", response.statusCode());
程序输出
Status 204
结论
我们学习了如何使用 Java HttpClient API 来使用 REST Web 服务。我们使用适当的 HTTP 方法执行 CRUD 操作,并检查响应以验证状态、标头和正文。
- 点赞
- 收藏
- 关注作者
评论(0)