1. 简介
在本教程中,我们将介绍几种在 Java 中将 HTTP 响应体读取为字符串的方式。从最早的版本开始,Java 就提供了 HttpURLConnection API。这个 API 功能基础,且使用起来不够友好。
到了 JDK 11,Java 引入了新的、更强大的 HttpClient API 来处理 HTTP 请求。我们将在本文中介绍这个 API,同时也会讲解其他一些常用的替代方案,比如 Apache HttpClient 和 Spring RestTemplate。
2. HttpClient
如前所述,HttpClient 是从 Java 11 开始引入的。它允许我们通过网络访问资源,与 HttpURLConnection 不同的是,HttpClient 支持 HTTP/1.1 和 HTTP/2 协议,并且 支持同步和异步请求。
HttpClient 提供了现代化的 API,具备良好的灵活性和强大的功能。其核心由三个类构成:HttpClient、HttpRequest 和 HttpResponse。
HttpResponse 表示一次 HttpRequest 调用的结果。⚠️ 注意:HttpResponse 不能直接创建,它是在响应体完全接收后才生成的。
要将响应体读取为字符串,我们首先需要创建一个简单的客户端和请求对象:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(DUMMY_URL))
.build();
然后使用 BodyHandlers 并调用 ofString() 方法来获取响应:
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
3. HttpURLConnection
HttpURLConnection 是一个轻量级的 HTTP 客户端,用于通过 HTTP 或 HTTPS 协议访问网络资源。它允许我们创建一个 InputStream,一旦获取了这个输入流,就可以像读取本地文件一样进行处理。
在 Java 中,主要通过 java.net.URL 类和 java.net.HttpURLConnection 类来访问网络资源。首先使用 URL 类指向一个网络资源,然后通过 HttpURLConnection 进行访问。
要将 URL 的响应体读取为字符串,首先需要使用 URL 创建一个 HttpURLConnection:
HttpURLConnection connection = (HttpURLConnection) new URL(DUMMY_URL).openConnection();
new URL(DUMMY_URL).openConnection() 返回一个 HttpURLConnection 对象,我们可以用它添加请求头或检查响应状态码。
接着,从 connection 对象获取 InputStream:
InputStream inputStream = connection.getInputStream();
最后一步是 **将 InputStream 转换为 String**。
4. Apache HttpClient
在本节中,我们将介绍如何使用 Apache HttpClient 来读取 HTTP 响应体为字符串。
首先需要在 Maven 项目中添加依赖:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2</version>
</dependency>
可以通过 CloseableHttpClient 类来发送和接收数据。使用 HttpClients.createDefault() 可以创建默认配置的实例。
CloseableHttpClient 提供了 execute 方法用于发送请求。该方法接受两个参数:第一个是 HttpUriRequest 类型(包括 HttpGet、HttpPost 等子类),第二个是 HttpClientResponseHandler,用于将响应转换为对象。
✅ 步骤如下:
- 创建 HttpGet 对象:
HttpGet request = new HttpGet(DUMMY_URL);
- 创建客户端:
CloseableHttpClient client = HttpClients.createDefault();
- 执行请求并获取响应字符串:
String response = client.execute(request, new BasicHttpClientResponseHandler());
logger.debug("Response -> {}", response);
这里使用了 BasicHttpClientResponseHandler,它会自动将响应体转换为字符串。
5. Spring RestTemplate
在本节中,我们将演示如何使用 Spring RestTemplate 读取 HTTP 响应体为字符串。⚠️ 需要注意的是,RestTemplate 已被标记为废弃,推荐使用下一节介绍的 Spring WebClient。
RestTemplate 是 Spring 提供的一个核心工具类,封装了底层 HTTP 客户端库(如 JDK HttpURLConnection、Apache HttpClient)的调用逻辑,简化了客户端 HTTP 操作。
它提供了多种便捷方法用于发送请求和处理响应。
首先添加 Maven 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
使用步骤如下:
- 创建 RestTemplate 实例:
RestTemplate restTemplate = new RestTemplate();
- 使用 getForObject 方法获取响应字符串:
String response = restTemplate.getForObject(DUMMY_URL, String.class);
6. Spring WebClient
最后,我们来看 Spring WebClient —— 响应式、非阻塞的替代方案,用于替代 RestTemplate。
添加 Maven 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
最简单的 GET 请求方式如下:
WebClient webClient = WebClient.create(DUMMY_URL);
执行 GET 请求并读取响应体为字符串:
Mono<String> body = webClient.get().retrieve().bodyToMono(String.class);
最后调用 block() 方法,等待整个响应体读取完成并返回字符串:
String s = body.block();
7. 总结
在本文中,我们介绍了多种将 HTTP 响应体读取为字符串的方式,包括:
- ✅ Java 11 的 HttpClient
- ✅ JDK 原生的 HttpURLConnection
- ✅ Apache HttpClient
- ✅ Spring 的 RestTemplate(已废弃)
- ✅ Spring 的 WebClient(推荐)
这些代码示例均可在 GitHub 上找到,分别是:
如你所见,每种方式都有其适用场景,选择时需结合项目需求和运行环境。