当前位置: 首页 > news >正文

☕️从小工到专家的 Java 进阶之旅:全新的HttpClient,现代高效的网络通信利器

☕️从小工到专家的 Java 进阶之旅:全新的HttpClient,现代高效的网络通信利器

你好,我是看山。

本文收录在 《从小工到专家的 Java 进阶之旅》 系列专栏。日拱一卒,功不唐捐。

在 Java 开发领域,网络通信一直是至关重要的部分。从早期的网络编程方式到如今,Java 在 HTTP 客户端方面经历了不断的演进。

其中,Java11 中正式推出的全新 HttpClient 带来了许多令人瞩目的变化。

一、Java HttpClient 的演进历程

在 Java 的发展历程中,HttpURLConnection 是早期进行 HTTP 通信的主要方式之一。然而,随着网络应用的日益复杂和对性能、功能的更高要求,它逐渐暴露出一些局限性。

传统的 HttpURLConnection 在处理复杂的网络交互场景时,代码编写相对繁琐,缺乏一些现代网络编程所需要的特性。例如,在异步处理、高效的并发操作以及对新的 HTTP 协议版本的支持方面表现不够理想。

而全新的 HttpClient 则应运而生,它是 Java 为了满足现代网络应用开发需求而设计的新一代 HTTP 客户端库。它的出现标志着 Java 在网络通信领域迈向了一个新的阶段,为开发者提供了更强大、更高效、更灵活的网络编程工具。

二、新 HttpClient 的特点与优势

(一)强大的功能特性

  1. 支持多种协议版本

    • 新的 HttpClient 同时支持 HTTP/1.1 和 HTTP/2。HTTP/2 相比 HTTP/1.1 在性能上有显著的提升,它通过多路复用、头部压缩等技术,减少了网络延迟,提高了数据传输效率。
    • 对于安全的网络通信,它也很好地支持了 HTTPS/TLS 协议,确保数据在传输过程中的安全性和完整性。
  2. 异步发送与通知机制

    • 支持异步操作是新 HttpClient 的一个重要特性。通过异步发送请求,应用程序可以在等待服务器响应的同时执行其他任务,提高了程序的并发处理能力。
    • 当异步请求完成时,客户端可以通过通知机制及时获取响应结果,这种机制使得程序的响应性更加出色。
  3. WebSocket 支持

    • WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。新 HttpClient 对 WebSocket 的支持使得 Java 应用程序能够轻松地构建实时的、双向通信的网络应用,如即时通讯、实时数据推送等。
  4. 响应式流

    • 响应式流是一种处理异步数据流的编程模型。新 HttpClient 与响应式流的集成,使得开发者可以更加高效地处理大量的异步数据,比如在处理实时数据更新或者大数据流传输的场景下,能够实现更平滑的数据处理和更低的资源消耗。

(二)简洁易用的 API

  1. 链式调用和流式操作

    • 新 HttpClient 的 API 设计非常简洁,它大量采用了链式调用和流式操作的方式。例如,在构建请求时,可以通过链式调用连续地设置请求方法、请求头、请求体等信息,使得代码更加清晰、简洁,易于理解和维护。
    • 这种设计模式符合现代编程的习惯,提高了开发效率。
  2. 与现有网络 API 一致的安全检查

    • 在安全方面,新 HttpClient 与 Java 现有的网络安全 API 保持了一致。它继承了 Java 安全模型的优势,在进行网络请求时,能够自动进行必要的安全检查,如证书验证、权限检查等,确保网络通信的安全可靠。

(三)高效的性能表现

  1. NIO 模型

    • 新 HttpClient 基于 NIO(Non - Blocking I/O)模型进行设计。NIO 模型能够在一个线程中处理多个连接,避免了传统阻塞 I/O 模型中线程被阻塞等待 I/O 操作完成的情况。
    • 这使得新 HttpClient 在高并发场景下能够高效地利用系统资源,大大提高了程序的吞吐量和响应速度。
  2. 函数式编程

    • 函数式编程的思想在新 HttpClient 中得到了充分的体现。通过使用函数式接口和 Lambda 表达式,开发者可以更加简洁地定义请求处理逻辑、响应处理逻辑等,减少了代码的冗余和复杂性。
  3. CompletableFuture 异步回调

    • CompletableFuture 是 Java 8 引入的一个用于异步编程的类。新 HttpClient 利用 CompletableFuture 实现异步回调机制,使得开发者可以方便地在异步操作完成后执行后续的处理逻辑。
    • 这种异步回调机制能够有效地避免阻塞,提高程序的并发性能。

三、新 HttpClient 的使用方法

(一)同步请求

以下是一个简单的同步请求的示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class HttpClientSyncExample {public static void main(String[] args) throws Exception {// 创建 HttpClient 对象HttpClient httpClient = HttpClient.newHttpClient();// 构建 HttpRequestHttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com")).GET().build();// 发送请求并获取 HttpResponseHttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());System.out.println("Response status code: " + httpResponse.statusCode());System.out.println("Response body: " + httpResponse.body());}
}

在上述示例中,首先通过HttpClient.newHttpClient()创建了一个 HttpClient 对象。然后使用HttpRequest.newBuilder()构建了一个 GET 请求,并指定了请求的 URL。最后通过httpClient.send()方法发送请求并获取响应。

(二)异步请求

异步请求的示例如下:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;public class HttpClientAsyncExample {public static void main(String[] args) throws Exception {// 创建 HttpClient 对象HttpClient httpClient = HttpClient.newHttpClient();// 构建 HttpRequestHttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com")).GET().build();// 发起异步请求并处理结果CompletableFuture<HttpResponse<String>> futureResponse = httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString());futureResponse.thenApply(response -> {System.out.println("Response status code: " + response.statusCode());System.out.println("Response body: " + response.body());return response;}).exceptionally(ex -> {System.out.println("Error occurred: " + ex.getMessage());return null;});// 主线程可以继续执行其他任务System.out.println("Main thread is doing other things...");// 等待异步操作完成futureResponse.join();}
}

在这个示例中,通过httpClient.sendAsync()方法发起异步请求,返回一个CompletableFuture对象。然后通过thenApply()方法在请求成功完成时处理响应,通过exceptionally()方法处理异常情况。

(三)发送 POST 请求

发送 POST 请求时,通常需要设置请求体。以下是一个示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;import java.nio.charset.StandardCharsets;public class HttpClientPostExample {public static void main(String[] args) throws Exception {HttpClient httpClient = HttpClient.newHttpClient();String requestBody = "data to be sent in the POST request";HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com/api")).POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)).header("Content-Type", "application/json").build();HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());System.out.println("Response status code: " + httpResponse.statusCode());System.out.println("Response body: " + httpResponse.body());}
}

在这个示例中,使用HttpRequest.BodyPublishers.ofString()方法设置了请求体,并指定了字符编码。同时,还设置了请求头中的Content - Typeapplication/json

(四)处理响应体

除了使用HttpResponse.BodyHandlers.ofString()来获取字符串形式的响应体,还可以使用其他的响应体处理器。例如,HttpResponse.BodyHandlers.ofByteArray()可以获取字节数组形式的响应体,HttpResponse.BodyHandlers.ofInputStream()可以获取输入流形式的响应体。

以下是一个使用HttpResponse.BodyHandlers.ofByteArray()的示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class HttpClientResponseBodyExample {public static void main(String[] args) throws Exception {HttpClient httpClient = HttpClient.newHttpClient();HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com/image.jpg")).GET().build();HttpResponse<byte[]> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofByteArray());byte[] responseBody = httpResponse.body();// 可以对字节数组形式的响应体进行进一步处理,比如保存为文件等}
}

(五)设置超时和重定向策略

可以自定义 HttpClient 的配置来设置超时时间和重定向策略。

设置超时时间的示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;import java.time.Duration;public class HttpClientTimeoutExample {public static void main(String[] args) throws Exception {HttpClient httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com")).GET().build();HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());System.out.println("Response status code: " + httpResponse.statusCode());System.out.println("Response body: " + httpResponse.body());}
}

在这个示例中,通过HttpClient.newBuilder().connectTimeout()方法设置了连接超时时间为 5 秒。

设置重定向策略的示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;import java.net.http.HttpClient.Redirect;public class HttpClientRedirectExample {public static void main(String[] args) throws Exception {HttpClient httpClient = HttpClient.newBuilder().followRedirects(Redirect.NEVER).build();HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://example.com/redirect")).GET().build();HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());System.out.println("Response status code: " + httpResponse.statusCode());System.out.println("Response body: " + httpResponse.body());}
}

在这个示例中,通过HttpClient.newBuilder().followRedirects()方法设置了重定向策略为从不重定向。

四、新 HttpClient 的未来展望

新 HttpClient 在 Java 网络通信中已经占据了重要的地位。随着 Java 技术的不断发展以及网络应用场景的不断拓展,它未来的发展方向和应用前景值得期待。

在未来,新 HttpClient 可能会进一步优化性能,尤其是在高并发、大数据量传输等极端场景下。它可能会与 Java 的其他新特性,如虚拟线程等进行更好的结合,以提供更加高效、稳定的网络通信能力。

在应用领域方面,新 HttpClient 将在微服务架构、分布式系统、物联网等领域发挥更大的作用。例如,在微服务架构中,服务之间的高效通信是关键,新 HttpClient 可以为服务间的 HTTP 调用提供更好的性能和可靠性。在物联网领域,大量的设备需要与服务器进行网络通信,新 HttpClient 可以满足物联网设备对高效、低资源消耗的网络通信的需求。

总之,Java 全新 HttpClient 是一个强大、高效、灵活的网络通信工具,它为 Java 开发者在现代网络应用开发中提供了有力的支持。随着它的不断发展和完善,相信它将在更多的领域得到广泛的应用。

文末总结

本文介绍了Java11提供的新版HttpClient的功能,在后续的开发过程中,我们就有了更多的选择。

青山不改,绿水长流,我们下次见。

推荐阅读

  • 从小工到专家的 Java 进阶之旅
  • 一文掌握 Java8 Stream 中 Collectors 的 24 个操作
  • 一文掌握 Java8 的 Optional 的 6 种操作
  • 使用 Lambda 表达式实现超强的排序功能
  • Java8 的时间库(1):介绍 Java8 中的时间类及常用 API
  • Java8 的时间库(2):Date 与 LocalDate 或 LocalDateTime 互相转换
  • Java8 的时间库(3):开始使用 Java8 中的时间类
  • Java8 的时间库(4):检查日期字符串是否合法
  • Java11 中基于嵌套关系的访问控制优化

http://www.mrgr.cn/news/48131.html

相关文章:

  • 设计模式的主要分类是什么?请简要介绍每个分类的特点。
  • LMDeploy 大模型推理框架介绍和实践
  • ICASSP 2025 中了 ,不去印度参会就撤稿?
  • 云原生周刊:利用 eBPF 增强 K8s
  • 第5章:基于EfficientNet 网络实现的图像分类任务:104种花种类识别
  • “AI 线索精益模型调用系统:开启精准营销新引擎
  • 每日OJ题_牛客_小乐乐改数字_模拟_C++_Java
  • 算法的收敛速度计算过程
  • 『网络游戏』进入游戏主城UI跳转主城【26】
  • Linux下的Makefile基本操作
  • Redis 的安装与部署(图文)
  • 中间件:SpringBoot集成Redis
  • FLBOOK一款强大的电子产品图册制作工具
  • springboot健康管理平台-计算机毕业设计源码38430
  • 【unity框架开发9】序列化字典,场景,vector,color,Quaternion
  • 孤独相伴 - 结婚十七年
  • 从数据到洞察:ChatGPT如何革新Python数据分析流程
  • 跟着深度学习好书实践tensorflow神经网络
  • NRF24L01原子HAl库学习
  • cuda实现gemm
  • numpy学习
  • 上门服务系统|上门服务小程序|上门服务系统成品
  • 2024系统分析师---试题四:论数据分片技术及其应用
  • 如何找到I2c设备的地址以及读写寄存器
  • AI核身-金融场景凭证篡改检测Baseline实践
  • 1 线性系统性能分析方法1——时域分析法