14

どうすればOutputStream使用できorg.apache.http.impl.client.DefaultHttpClientますか?

出力ストリームに長い文字列を書きたいと思っています。

あなたを使用HttpURLConnectionすると、次のように実装されます:

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

上記と同様の方法はありDefaultHttpClientますか?代わりにOutputStreamusingに書き込むにはどうすればよいですか?DefaultHttpClientHttpURLConnection

例えば

DefaultHttpClient client = new DefaultHttpClient();

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

4 に答える 4

30

別の回答がすでに受け入れられていることは知っています。念のために言っておきますが、これは、メモリに中間バッファリングを行わずに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);
于 2012-04-14T09:52:15.410 に答える
15

BasicHttpClientからOutputStreamを直接取得することはできません。オブジェクトを作成し、送信するコンテンツをカプセル化するHttpUriRequestオブジェクトを指定する必要があります。HttpEntityたとえば、出力がメモリに収まるほど小さい場合は、次のようにします。

// 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);

HttpEntityデータがストリーミングする必要があるほど大きい場合、OutputStreamを受け入れる実装がないため、データはより困難になります。一時ファイルに書き込んで使用するFileEntityか、場合によってはパイプを設定して使用する必要がありますInputStreamEntity

編集コンテンツをストリーミングする方法を示すサンプルコードについては、olegの回答を参照してください。結局、一時ファイルやパイプは必要ありません。

于 2012-04-13T19:50:05.017 に答える
3

これはAndroidでうまく機能しました。バッファリングが必要ないため、大きなファイルでも機能するはずです。

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
于 2014-04-25T09:12:00.590 に答える
2

Apache Commons HTTPClient4.3.4を使用してHTTPPOSTのOutputStreamインターフェイスを提供するApacheのHTTPクライアントAPI [PipedApacheClientOutputStream]の反転を作成しました。

市外局番は次のようになります。

// 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();

-実際には、同じクライアント、エグゼキューターサービス、および構成がアプリケーションの存続期間を通じて再利用される可能性が高いため、上記の例の外部のprepおよびcloseコードは、直接インラインではなく、bootstrap/initおよびfinalizationコードに存在する可能性があります。 OutputStreamのインスタンス化。

于 2016-03-07T17:03:59.480 に答える