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

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE)流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会导致数据必须等待全部接收完毕后再处理,违背了流式传输的初衷。

本文将介绍如何在 Spring Boot 2.7.x 中使用 RestTemplate 实现一个流式响应的中转接口。

一、关键点说明

  1. 禁用请求缓冲:
    通过 SimpleClientHttpRequestFactory#setBufferRequestBody(false) 禁用缓冲,确保流式传输生效。

  2. 设置响应为 SSE 格式:
    设置 HttpServletResponse 的响应头为 text/event-stream,支持前端基于 EventSource 的实时响应。

  3. 使用 RestTemplate.execute 方法:
    通过 RestTemplate.execute() 方法自定义 RequestCallbackResponseExtractor 实现对输入输出流的精细控制。

二、完整代码实现

/*** 处理流式响应的HTTP请求方法(流式响应, Spring Boot 2.7.x 兼容)** @param requestBody 请求体内容* @param url         请求URL* @param httpMethod  请求方法* @param response    HttpServletResponse,用于直接返回流数据*/
public static void executeStreamingRequest(Map<String, Object> requestBody,String url,HttpMethod httpMethod,HttpServletResponse response) throws IOException {// 1. 配置RestTemplate(启用流式)SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();requestFactory.setBufferRequestBody(false); // 关键:禁用请求缓冲requestFactory.setConnectTimeout(30000);requestFactory.setReadTimeout(60000);RestTemplate restTemplate = new RestTemplate(requestFactory);// 2. 设置请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);// 3. 执行流式请求try {log.info("【开始流式请求】URL: {}", url);restTemplate.execute(URI.create(url),httpMethod,new RequestCallback() {@Overridepublic void doWithRequest(ClientHttpRequest request) throws IOException {request.getHeaders().putAll(headers);if (requestBody != null) {new ObjectMapper().writeValue(request.getBody(), requestBody);}}},new ResponseExtractor<Void>() {@Overridepublic Void extractData(ClientHttpResponse clientResponse) throws IOException {// 设置响应头response.setContentType("text/event-stream");response.setCharacterEncoding("UTF-8");// 流式传输try (InputStream is = clientResponse.getBody();OutputStream os = response.getOutputStream()) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {os.write(buffer, 0, bytesRead);os.flush(); // 立即刷新}}return null;}});} catch (RestClientException e) {log.error("流式请求失败", e);response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);response.getWriter().write("服务调用失败: " + e.getMessage());}
}

三、使用场景举例

  • 转发 OpenAI 的流式 API 响应

  • 转发后端 AI 推理接口的逐步响应

  • 转发日志、进度等后台任务推送数据

四、注意事项

  • 保证上下游接口支持长连接和流式传输

  • 防止浏览器缓冲影响效果,前端建议使用 EventSourcefetch + reader 模式消费

  • 若上游响应为分块传输(chunked),务必确保 header 中包含 Transfer-Encoding: chunked

一线网资源-全网一站式平台

http://www.lqws.cn/news/169741.html

相关文章:

  • 23套橙色系精选各行业PPT模版分享
  • windows上的visual studio2022的项目使用jenkins自动打包
  • 极速互联·智控未来——SG-Can(FD)Hub-600 六通道CANFD集线器
  • 【Go语言基础【9】】字符串格式化与输入处理
  • Docker配置SRS服务器 ,ffmpeg使用rtmp协议推流+vlc拉流
  • 8K样本在DeepSeek-R1-7B模型上的复现效果
  • Axure零基础跟我学:展开与收回
  • 【美团技术团队】从实际案例聊聊Java应用的GC优化
  • Python应用函数调用(二)
  • Nginx部署vue项目, 无法直接访问其他路径的解决方案
  • [AI绘画]sd学习记录(一)软件安装以及文生图界面初识、提示词写法
  • 渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
  • React 新项目
  • 环境变量深度解析:从配置到内核的全链路指南
  • Python制作史莱姆桌面宠物!可爱的
  • 风机下引线断点检测算法实现
  • Linux程序运行日志总结
  • 整合swagger,以及Knife4j优化界面
  • 【leetcode】347. 前k个高频元素
  • 动态规划-1035.不相交的线-力扣(LeetCode)
  • 微服务网关SpringCloudGateway+SaToken鉴权
  • Vue3入门指南:从零到精通的快速上手
  • CSS3相关知识点
  • linux——磁盘和文件系统管理
  • [蓝桥杯]植树
  • 强化学习入门:Gym实现CartPole随机智能体
  • 五、Sqoop 增量导入:精通 Append 与 Lastmodified 模式
  • Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
  • 世事无常,比较复杂,人可以简单一点
  • 基于大模型的原发性醛固酮增多症全流程预测与诊疗方案研究