How do I write to an OutputStream using DefaultHttpClient?

后端 未结 4 1890
挽巷
挽巷 2020-12-09 05:10

How do I get an OutputStream using org.apache.http.impl.client.DefaultHttpClient?

I\'m looking to write a long string to an output stream.

相关标签:
4条回答
  • 2020-12-09 05:46

    You can't get an OutputStream from BasicHttpClient directly. You have to create an HttpUriRequest object and give it an HttpEntity that encapsulates the content you want to sent. 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. You'd need to write to a temp file and use FileEntity or possibly set up a pipe and use 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.

    0 讨论(0)
  • 2020-12-09 05:57

    This worked well on 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
    
    0 讨论(0)
  • 2020-12-09 05:58

    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.

        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);
    
    0 讨论(0)
  • 2020-12-09 06:09

    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.

    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.

    0 讨论(0)
提交回复
热议问题