Java 中的 Http 客户端 API:基础知识

举报
千锋教育 发表于 2023/07/24 13:18:02 2023/07/24
【摘要】 概述Java 11 中引入了新的 HttpClient API。它是不适合 HTTP 协议的旧 HttpURLConnection API 的替代品。这个新的 API 使用构建器模式和流畅的 API 来创建通过网络进行通信所需的对象。它还提供以下功能:支持HTTP2协议。SSL 加密。同步和异步通信模型。支持 HTTP 方法。身份验证机制(基本)。饼干。API 包含三个主要类:HttClie...

企业微信截图_20230724131720.jpg

概述

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

程序输出

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 操作,并检查响应以验证状态、标头和正文。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。