在我的团队中,我们遇到了一个特定端点的问题,当使用一些特定参数调用该端点时,它会提供一个巨大的JSON块。因此,例如,如果JSON有1,000行,在使用浏览器打开URL大约30秒后(这是一个GET端点)我们得到100行,然后再等几行,得到下一个200行,等等,直到JSON耗尽为止。这对我们来说是个问题,因为我们的应用程序在检索JSON之前超时。我们希望用我们自己的示例端点来模拟端点的行为,用于调试目的。
到目前为止,我已经完成了以下操作。为了简单起见,我甚至没有阅读JSON,只是随机生成的字符串。日志显示我一次读取几个字节的数据,写入数据并刷新OutputStream
。关键的区别在于我的浏览器(或 Postman )给我看数据 * 在最末端 *,而不是成块的。我能做些什么来使它让我能看到数据成块地回来吗?
private static final int readBufSize = 10;
private static final int generatedStringSize = readBufSize * 10000;
@GetMapping(path = "/v2/payload/mocklargepayload")
public void simulateLargePayload(HttpServletResponse response){
try(InputStream inputStream = IOUtils.toInputStream(RandomStringUtils.randomAlphanumeric(generatedStringSize));
OutputStream outputStream = response.getOutputStream()) {
final byte[] buffer = new byte[readBufSize];
for(int i = 0; i < generatedStringSize; i+= readBufSize){
inputStream.read(buffer, 0, readBufSize - 1);
buffer[buffer.length - 1] = '\n';
log.info("Read bytes: {}", buffer);
outputStream.write(buffer);
log.info("Wrote bytes {}", buffer);
Thread.sleep(500);
log.info("Flushing stream");
outputStream.flush();
}
} catch (IOException | InterruptedException e) {
log.error("Received exception: {}", e.getClass().getSimpleName());
}
}
1条答案
按热度按时间n9vozmp41#
你的端点应该返回一个标头"content-length",在这里你将指定端点返回的信息的总大小。这将通知你的客户端需要多少信息。另外,你可以在信息可用时逐块读取信息。我遇到了一个相反的问题,我在端点中写入了一个很大的输入(POST)。端点读取它的速度比我写的速度快,所以在某个时候,当它读取到目前为止所有可用的信息时,它会停止读取,认为这就是它。所以,我写了下面的代码,你可以在客户端以同样的方式实现它:
另外,我为读/写编写了一个通用特性,也遇到了同样的问题(同样适用于服务器端),但同样你也可以在客户端实现相同的逻辑。该特性在信息可用时读取信息块。该特性随开源库MgntUtils提供(由我编写和维护)。参见类WebUtils。包含源代码和Javadoc的库可以在Github here. Javadoc is here上获得。它也可以作为Maven artifact here获得