学习调用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;
}
});