【问题标题】:How do I stream the body of an HTTP request using Java如何使用 Java 流式传输 HTTP 请求的正文
【发布时间】:2019-02-06 12:10:34
【问题描述】:

我有一个InputStream 和将要输出的数据的大小(HTTP 请求的响应)。由于空间复杂性的原因,我无法阅读整个内容。我想要的是将数据直接发送到新的请求正文中。我试过用 OkHttp 做这个,但我不能让它工作。我不知道有任何其他 HTTP 客户端可以做到这一点。

如果可能的话,我想避免与Socket 混在一起。有什么建议吗?

编辑:增加的限制是解决方案必须与 Java 8 一起使用

【问题讨论】:

标签: java http streaming


【解决方案1】:

我相信 Java 11 中标准化的新 HttpClient 应该可以让您做到这一点。它使用Flow API(反应式流),您可以提供BodyHandler/BodySubscriber 来请求/接收字节。 HttpClient 还允许您在发送请求时指定 BodyPublisher。因此,只需将请求发布者转发给其订阅者的订阅绑定到 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)

【讨论】:

  • 这真的很酷。唉,我所在的公司环境卡在 Java 8 上,不允许我升级。
  • 哦 - 太糟糕了。您可以使用执行程序来抽取 InputStream 并将其传输到请求吗?旧的 http 堆栈 (HttpURLConnection) 将请求主体公开为 OutputStream - 因此,如果您可以使用执行线程进行传输...
  • 我考虑过,但是 HttpURLConnection 类被破坏了,使用常规套接字并手动编写请求可能更容易。
  • 嗯 - 在 11 中有一个新的 API 是有原因的...至于直接使用普通套接字,您可能会对潜伏在任何 HTTP 实现中的所有小黑边情况感到惊讶。跨度>
【解决方案2】:

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

虽然旧的现有 HttpUrlConnection 类或任何提供对与​​给定 Url 连接关联的输入和输出流的访问的任何东西都可以支持流式传输,但您也可能必须编写过多的支持代码用于新的安全问题,例如 OPTIONS。

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    相关资源
    最近更新 更多