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;
    }
});
相关推荐
这人很懒没留下什么12 小时前
SpringBoot2.7.4整合RabbitMq
rabbitmq·springboot
千寻技术帮18 小时前
50036_基于微信小程序的智能点餐推荐系统
小程序·源码·springboot·文档
言一木21 小时前
【国产化】金蝶MQ验证
springboot·国产化·消息中间件
这周也會开心1 天前
SpringBootTest和SpringBootApplication
springboot
她说..2 天前
基于Redis实现的分布式唯一编号生成工具类
java·数据库·redis·分布式·springboot
最后1112 天前
lamp-cloud 5.7.0 发布,新增缓存清理 + 修复优化全覆盖
java·后端·spring·缓存·springboot·springcloud
bcgbsh5 天前
身份认证状态的存储与传递( Spring Boot篇 )
springboot·登录
xiezhr5 天前
Java开发中最那些常见的坑,你踩过几个?
java·spring·springboot·后端开发
原来是好奇心7 天前
Spring Boot缓存实战:@Cacheable注解详解与性能优化
java·spring·mybatis·springboot
千寻技术帮8 天前
50013_基于微信小程序的校园志愿者系统
mysql·微信小程序·springboot·文档·ppt