Java 11 中新的 HttpClient API概览

概述

Java 11 中引入了新的 HttpClient API。它替代了不适合 HTTP 协议的旧 HttpURLConnection API。这个新的 API 使用构建器模式和流畅的 API 来创建所需的对象以通过网络进行通信。它还提供以下功能:

  1. 支持HTTP2协议。
  2. SSL 加密。
  3. 同步和异步通信模型。
  4. 支持 HTTP 方法。
  5. 身份验证机制(基本)。
  6. 饼干。

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 对象(如 String)的便捷方法。

程序输出

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
  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youtian.L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值