Java 流式返回 JSON 分段提取的实战指南
在现代开发中,越来越多的应用需要从后端以 JSON 格式获取数据。处理这些数据时,如果一次性加载全部内容,可能会导致内存占用过高或响应时间延长。因此,我们需要采用流式处理(Streaming)的方法进行分段提取数据。
在这篇文章中,我将带领你了解整个过程,并通过具体的示例代码来帮助你实现这一目标。
任务流程概述
以下是实现Java流式返回JSON分段提取的主要步骤:
步骤 | 描述 |
---|---|
1 | 创建一个 RESTful API |
2 | 设计用于流式响应的 DTO(数据传输对象) |
3 | 使用 StreamingResponseBody 接口进行流式返回 |
4 | 处理 JSON 数据的提取和传输 |
5 | 在客户端使用流处理数据 |
步骤详解
1. 创建一个 RESTful API
首先,我们需要创建一个基本的 Spring Boot 应用,并添加依赖项:
<!-- 在 pom.xml 中添加依赖项 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
接下来,创建一个控制器类来处理请求:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
@RestController
public class DataController {
@GetMapping("/data")
public StreamingResponseBody streamData() {
// 这里将实现流式返回逻辑
}
}
2. 设计用于流式响应的 DTO
定义一个数据传输对象(DTO)来封装返回的数据:
public class DataDTO {
private String id;
private String content;
// 构造函数,getter和setter省略
}
3. 使用 StreamingResponseBody
接口进行流式返回
我们将使用 StreamingResponseBody
来实现流式响应:
@GetMapping("/data")
public StreamingResponseBody streamData() {
return outputStream -> {
// 需要重点查看这里
// 设定输出格式
outputStream.write("[".getBytes());
for (int i = 0; i < 100; i++) {
// 创建数据对象
DataDTO data = new DataDTO();
data.setId(String.valueOf(i));
data.setContent("Content " + i);
// 将对象转换成 JSON 格式
String json = convertToJson(data);
// 写入到输出流
outputStream.write(json.getBytes());
if (i < 99) {
outputStream.write(",".getBytes()); // 添加分隔符
}
outputStream.flush(); // 刷新输出流以确保数据被及时发送
}
outputStream.write("]".getBytes());
outputStream.flush(); // 刷新最后的输出流
};
}
private String convertToJson(DataDTO data) {
// 使用Jackson或Gson库将对象转换为JSON字符串
return new ObjectMapper().writeValueAsString(data);
}
4. 处理 JSON 数据的提取和传输
在上面的代码中,convertToJson
方法使用 Jackson 库将 DTO 对象转换为 JSON 格式。在控制器中,我们创建了流式响应,并逐个将 JSON 数据对象写入输出流,如果输出过多数据则会使用 flush()
方法将其发送出去。
5. 在客户端使用流处理数据
在客户端,您可以使用 JavaScript 的 Fetch API 来处理服务器发送的流式数据:
fetch('/data')
.then(response => {
const reader = response.body.getReader();
let decoder = new TextDecoder();
let result = '';
reader.read().then(function processText({ done, value }) {
if (done) {
// 处理完成
console.log('Stream finished');
return;
}
result += decoder.decode(value, { stream: true });
console.log(result); // 输出当前接收到的数据
return reader.read().then(processText);
});
});
关系图
以下是使用 mermaid 语法生成的关系图,展示了整个数据流转的结构:
erDiagram
DATA {
string id
string content
}
REST_API {
string endpoint
string method
}
REST_API ||--o{ DATA : returns
旅行图
继续使用 mermaid 语法,展示客户端如何接收和处理流数据的过程:
journey
title 客户端获取流式返回数据的过程
section 从服务器请求数据
用户点击请求数据按钮: 5: 用户
发送 GET 请求: 5: 客户端
section 获取数据
开始读取流: 4: 客户端
持续接收数据: 5: 客户端
section 数据处理
输出接收到的数据: 5: 客户端
结尾
通过以上步骤,我们实现了 Java 流式返回 JSON 分段提取的功能。使用流式处理可以大大减少内存消耗,提升性能。希望这篇文章能帮助你更好地理解和应用流式数据处理的概念。
如果在实现过程中有任何问题,欢迎随时询问!