![](/img/trans.png)
[英]How to write a request body using a stream with the java 11 http client?
[英]How do I stream the body of an HTTP request using Java
我有一个InputStream
和将要输出的数据的大小(HTTP 请求的响应)。 出于空间复杂性的原因,我无法阅读全部内容。 我想要的是将数据直接发送到新的请求正文中。 我试过用 OkHttp 这样做,但我无法让它工作。 我不知道有任何其他 HTTP 客户端可以执行此操作。
如果可能的话,我想避免乱用Socket
。 有什么建议吗?
编辑:添加的限制是该解决方案必须与 Java 8 一起使用
我相信 Java 11 中标准化的新HttpClient
应该可以让你做到这一点。 它使用Flow
API(反应性流),您可以提供一个BodyHandler
/ BodySubscriber
来请求/接收字节。 HttpClient
还允许您在发出请求时指定BodyPublisher
。 所以它应该只是将请求发布者转发给它的订阅者的订阅BodySubscriber
到由 Http 堆栈分发给BodySubscriber
的订阅,然后让BodySubscriber
的onNext
(等等)调用Publisher
的订阅者对应的方法。 请注意,这是一个学术描述:我实际上并没有尝试实施它。 设置订阅链接可能需要一些思考和一些技巧,但我相信它应该有效。
但是,请确保您的BodySubscriber
/ BodyPublisher
遵循反应式流语义 - 并且它们不会在回调中阻塞。
https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html https://openjdk.java.net/groups/net /httpclient/intro.html
再想一想,这可能不是您要问的:如果您已经有了InputStream
那就更简单了:只需在发送请求时使用BodyPublishers.ofInputStream
。
我要补充的是,如果请求的大小足够您想要实现流式传输,那么接收服务也可能希望实现流式传输。
同样,虽然较旧的现有 HttpUrlConnection 类,或任何提供对与给定 Url 连接关联的输入和输出流的访问权限的东西都可以支持流式传输,但您也可能必须为新的安全性编写过多的支持诸如 OPTIONS 之类的问题。
你可以这样做:
File file = new File("path_to_file"); // specify path to the large file you want to upload
InputStream inputStream = new FileInputStream(file); // Create input stream out of the file. This will be used to stream data directly to request body
HttpURLConnection connection = (HttpURLConnection) new URL("remote_url").openConnection(); // Open connection. This will not send eny request until explicitly asked.
connection.setDoOutput(true); // This will set http method to POST
connection.setFixedLengthStreamingMode(file.length()); // Define the length of the request body size
OutputStream output = connection.getOutputStream(); // This is the output stream of the request body. It will be used to stream file bytes into.
var bytes = inputStream.readNBytes(1024); // Read the first 1024 bytes from the file
// Following while loop will read chunks of 1024 bytes from the file and write them into the request body output stream.
// Note the use of the flush function. It will send the current content of the output stream to the remote server.
while (bytes.length > 0) {
output.write(bytes);
output.flush();
bytes = inputStream.readNBytes(1024);
}
connection.connect(); // This finishes request and returns response
我用它来与 Flussonic 集成,它完成了工作。
您可以使用此答案进行进一步研究: https://stackoverflow.com/a/2793153/11676066
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.