RestTemplate实时接收Chunked编码传输的HTTP Response

学习调用AI接口的时候,流式响应都是使用的 Transfer-Encoding: chunked,图方便想用RestTemplate,但是平时用到的都是直接返回响应对象的类型。使用bing搜索到一种方式,使用下面的代码来读取,于是掉这个坑里了,浪费了我好长时间。

java 复制代码
ResponseEntity<Resource> responseEntity = restTemplate.exchange(apiUrl, HttpMethod.POST, requestEntity, org.springframework.core.io.Resource.class);
PrintWriter writer = httpServletResponse.getWriter();
BufferedReader bufferedReader;
try {
    bufferedReader = new BufferedReader(new InputStreamReader(responseEntity.getBody().getInputStream()));
    String line;
    while ((line = bufferedReader.readLine()) != null && !(ChatGpt3dot5Request.STREAM_MESSAGE_PREFIX + "[DONE]").equals(line)) {
        String message = getMessageFromLine(line, ChatGpt3dot5Request.STREAM_MESSAGE_PREFIX);
        writer.write(message);
        writer.flush();
    }
} catch (IOException e) {
    throw new RuntimeException(e);
}

注意,上面的代码是错误的,并不会实时读取到数据,而是会等到响应全结束之后才能读取到数据。


下面的才是正解:

java 复制代码
restTemplate.execute(apiUrl, HttpMethod.POST, restTemplate.httpEntityCallback(requestEntity), new ResponseExtractor<ClientHttpResponse>() {
    @Override
    public ClientHttpResponse extractData(ClientHttpResponse response) throws IOException {
        InputStream inputStream = response.getBody();
        /*
         * 在这个地方从inputStream中读取数据,或者调用自己的方法读取inputStream来处理数据
        */
        return response;
    }
});
相关推荐
敲代码的嘎仔21 小时前
Java后端面试——SSM框架面试题
java·面试·职场和发展·mybatis·ssm·springboot·八股
洛阳泰山2 天前
MaxKB4j Docker Compose 部署指南
java·docker·llm·springboot·rag·maxkb4j
l软件定制开发工作室2 天前
Spring开发系列教程(34)——打包Spring Boot应用
java·spring boot·后端·spring·springboot
我是TT啊2 天前
GaussDB_DWS连接池问题排查记录
springboot·gaussdb·druid
苏渡苇2 天前
Stream.collect() 的花式玩法:Collector.of() 自定义收集器
java·stream·jdk21·collector·jdk8+·自定义收集器
洛阳泰山4 天前
开源智能体搭建平台MaxKB4j 技术文档
java·开源·llm·springboot·agent·rag·langchain4j
生产队队长5 天前
SpringBoot3:应用程序启动时,初始化工作[官方文档]
springboot
闻哥5 天前
MySQL索引核心原理:B+树生成、页分裂与页合并全解析
java·jvm·b树·mysql·adb·面试·springboot
C雨后彩虹7 天前
深入探索Java Stream:6个复杂业务场景下的高效实现方案
java·多线程·stream·同步·异步