简体   繁体   English

如何使用DefaultHttpClient写入OutputStream?

[英]How do I write to an OutputStream using DefaultHttpClient?

How do I get an OutputStream using org.apache.http.impl.client.DefaultHttpClient ? 如何使用org.apache.http.impl.client.DefaultHttpClient获取OutputStream

I'm looking to write a long string to an output stream. 我正在寻找一个输出流的长字符串。

Using HttpURLConnection you would implement it like so: 使用HttpURLConnection您可以像这样实现它:

HttpURLConnection connection = (HttpURLConnection)url.openConnection();
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
writeXml(wout);

Is there a method using DefaultHttpClient similar to what I have above? 是否有一个方法使用DefaultHttpClient类似于我上面的方法? How would I write to an OutputStream using DefaultHttpClient instead of HttpURLConnection ? 如何使用DefaultHttpClient而不是HttpURLConnection写入OutputStream

eg 例如

DefaultHttpClient client = new DefaultHttpClient();

OutputStream outstream = (get OutputStream somehow)
Writer wout = new OutputStreamWriter(out);

I know that another answer has already been accepted, just for the record this is how one can write content out with HttpClient without intermediate buffering in memory. 我知道另一个答案已被接受,只是为了记录这是如何用HttpClient写出内容而不在内存中进行中间缓冲。

    AbstractHttpEntity entity = new AbstractHttpEntity() {

        public boolean isRepeatable() {
            return false;
        }

        public long getContentLength() {
            return -1;
        }

        public boolean isStreaming() {
            return false;
        }

        public InputStream getContent() throws IOException {
            // Should be implemented as well but is irrelevant for this case
            throw new UnsupportedOperationException();
        }

        public void writeTo(final OutputStream outstream) throws IOException {
            Writer writer = new OutputStreamWriter(outstream, "UTF-8");
            writeXml(writer);
            writer.flush();
        }

    };
    HttpPost request = new HttpPost(uri);
    request.setEntity(entity);

You can't get an OutputStream from BasicHttpClient directly. 您无法直接从BasicHttpClient获取OutputStream。 You have to create an HttpUriRequest object and give it an HttpEntity that encapsulates the content you want to sent. 您必须创建一个HttpUriRequest对象并为其提供一个封装您要发送的内容的HttpEntity For instance, if your output is small enough to fit in memory, you might do the following: 例如,如果输出小到足以适合内存,则可能会执行以下操作:

// Produce the output
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writeXml(writer);

// Create the request
HttpPost request = new HttpPost(uri);
request.setEntity(new ByteArrayEntity(out.toByteArray()));

// Send the request
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request);

If the data is large enough that you need to stream it, it becomes more difficult because there's no HttpEntity implementation that accepts an OutputStream. 如果数据足够大以至于需要对其进行流式处理,则会变得更加困难,因为没有接受OutputStream的HttpEntity实现。 You'd need to write to a temp file and use FileEntity or possibly set up a pipe and use InputStreamEntity 您需要写入临时文件并使用FileEntity或可能设置管道并使用InputStreamEntity

EDIT See oleg's answer for sample code that demonstrates how to stream the content - you don't need a temp file or pipe after all. 编辑请参阅oleg的答案,了解演示如何流式传输内容的示例代码 - 毕竟,您不需要临时文件或管道。

This worked well on android. 这在android上运行良好。 It should also work for large files, as no buffering is needed. 它也适用于大文件,因为不需要缓冲。

PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream();
out.connect(in);
new Thread() {
    @Override
    public void run() {
        //create your http request
        InputStreamEntity entity = new InputStreamEntity(in, -1);
        request.setEntity(entity);
        client.execute(request,...);
        //When this line is reached your data is actually written
    }
}.start();
//do whatever you like with your outputstream.
out.write("Hallo".getBytes());
out.flush();
//close your streams

I wrote an inversion of Apache's HTTP Client API [PipedApacheClientOutputStream] which provides an OutputStream interface for HTTP POST using Apache Commons HTTP Client 4.3.4. 我写了一个Apache的HTTP客户端API [PipedApacheClientOutputStream]的反转,它使用Apache Commons HTTP Client 4.3.4为HTTP POST提供了一个OutputStream接口。

Calling-code looks like this: 调用代码如下所示:

// Calling-code manages thread-pool
ExecutorService es = Executors.newCachedThreadPool(
  new ThreadFactoryBuilder()
  .setNameFormat("apache-client-executor-thread-%d")
  .build());


// Build configuration
PipedApacheClientOutputStreamConfig config = new      
  PipedApacheClientOutputStreamConfig();
config.setUrl("http://localhost:3000");
config.setPipeBufferSizeBytes(1024);
config.setThreadPool(es);
config.setHttpClient(HttpClientBuilder.create().build());

// Instantiate OutputStream
PipedApacheClientOutputStream os = new     
PipedApacheClientOutputStream(config);

// Write to OutputStream
os.write(...);

try {
  os.close();
} catch (IOException e) {
  logger.error(e.getLocalizedMessage(), e);
}

// Do stuff with HTTP response
...

// Close the HTTP response
os.getResponse().close();

// Finally, shut down thread pool
// This must occur after retrieving response (after is) if interested   
// in POST result
es.shutdown();

Note - In practice the same client, executor service, and config will likely be reused throughout the life of the application, so the outer prep and close code in the above example will likely live in bootstrap/init and finalization code rather than directly inline with the OutputStream instantiation. - 实际上,相同的客户端,执行程序服务和配置可能会在应用程序的整个生命周期中重复使用,因此上面示例中的外部准备和关闭代码可能存在于bootstrap / init和finalization代码中,而不是直接与内联OutputStream实例化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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