繁体   English   中英

我如何使用 Java HTTP 请求的正文 stream

[英]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的订阅,然后让BodySubscriberonNext (等等)调用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

https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.BodyPublishers.html#ofInputStream(java.util.function.Supplier)

我要补充的是,如果请求的大小足够您想要实现流式传输,那么接收服务也可能希望实现流式传输。

同样,虽然较旧的现有 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM