【问题标题】:HTTP sending request content before knowing its size (org.apache.http)HTTP 在知道其大小之前发送请求内容 (org.apache.http)
【发布时间】:2012-08-28 22:57:57
【问题描述】:

我想在创建整个数据之前开始向 HTTP 服务器发送数据。

当您使用 java.net.HttpURLConnection 时,这很容易:

urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);

dos = new DataOutputStream(urlConnection.getOutputStream());
...
dos.writeShort(s);
...

但由于某些原因,我想使用 org.apache.http 包(我必须开发一个基于包 org.apache.http 的库)。我已经阅读了它的文档,但是我没有找到与上面的代码类似的任何东西。是否可以在知道最终数据大小之前使用 org.apache.http 包将数据分块发送到 HTTP 服务器?

提前感谢所有建议;)

【问题讨论】:

  • HttpCore 似乎支持 Chunk 编码。如果 isChunked() 返回 true,则可以分块发送 HttpEntity。如何使用它们或使用什么合适的实体我还不知道。
  • 我之前知道org.apache.http包支持分块发送内容,但是当http连接建立时我找不到发送大小未知的内容的方法。但是我更深入地研究了文档,我在 BasicHttpEnitity (hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/…) 中找到了一个方法 setContent(InputStream instream)。就是这样;)
  • 然后回答你自己的问题。它很可能会帮助其他尝试这样做的人。 :)

标签: java http


【解决方案1】:

在不知道其最终大小的情况下以块发送数据也很容易使用 Apache 库。这是一个简单的例子:

DataInputStream dis;
...
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:8080");

BasicHttpEntity entity = new BasicHttpEntity();
entity.setChunked(true);
entity.setContentLength(-1);
entity.setContent(dis);

httppost.setEntity(entity);
HttpResponse response = null;
try {
     response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
    // TODO
} catch (IOException e) {
    // TODO
}
...
// processing http response....

dis 是一个应该包含实体主体的流。您可以使用管道流将dis 输入流与输出流连接起来。因此,一个线程可能正在创建数据(例如从麦克风录制声音),而另一个线程可能会将其发送到服务器。

// creating piped streams
private PipedInputStream pis;
private PipedOutputStream pos;
private DataOutputStream dos;
private DataInputStream dis;

...

pos = new PipedOutputStream();
pis = new PipedInputStream(pos);
dos = new DataOutputStream(pos);
dis = new DataInputStream(pis);

// in thread creating data dynamically
try {
    // writing data to dos stream
    ...
    dos.write(b);
    ...
} catch (IOException e) {
    // TODO
}

// Before finishing thread, we have to flush and close dos stream
// then dis stream will know that all data have been written and will finish
// streaming data to server.
try {
    dos.flush();
    dos.close();
} catch (Exception e) {
    // TODO
}

dos 应该传递给动态创建数据的线程,dis 应该传递给向服务器发送数据的线程。

另请参阅:http://www.androidadb.com/class/ba/BasicHttpEntity.html

【讨论】:

  • 我真的不喜欢那些 PipedStreams,但我想制作块的关键技巧就在那里。
  • 如果您建议将数据从一个线程发送到另一个线程的更好解决方案,我将不胜感激;)
  • 我对这些流的看法似乎在这个问题中得到了很好的解释。 stackoverflow.com/questions/484119/… 我还了解到,从一端关闭管道将立即关闭另一端,防止所有剩余数据到达输入流管道端。在我的一个项目中,我创建了自己的缓冲区类并用锁和条件包装了它,但可能还有其他更好的高级方法。
猜你喜欢
  • 2020-04-23
  • 1970-01-01
  • 2015-04-14
  • 2012-07-04
  • 2012-05-27
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多