org.Apache.http.impl.client.DefaultHttpClient
を使用してOutputStream
を取得するにはどうすればよいですか?
長い文字列を出力ストリームに書きたいと思っています。
HttpURLConnection
を使用すると、次のように実装できます。
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
writeXml(wout);
上記と同様のDefaultHttpClient
を使用する方法はありますか? OutputStream
の代わりにDefaultHttpClient
を使用してHttpURLConnection
に書き込むにはどうすればよいですか?
例えば
DefaultHttpClient client = new DefaultHttpClient();
OutputStream outstream = (get OutputStream somehow)
Writer wout = new OutputStreamWriter(out);
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);
データがストリーミングする必要があるほど大きい場合、OutputStreamを受け入れるHttpEntity
実装がないため、より困難になります。一時ファイルに書き込んでFileEntity
を使用するか、パイプを設定してInputStreamEntity
を使用する必要があります。
[〜#〜] edit [〜#〜]コンテンツをストリーミングする方法を示すサンプルコードについては、olegの回答を参照してください-結局、一時ファイルやパイプは必要ありません。
別の答えがすでに受け入れられていることを私は知っています。記録のために、これは、メモリに中間バッファリングすることなく、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);
これは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
ApacheのHTTPクライアントAPIの反転を作成しました [PipedApacheClientOutputStream] これはApache CommonsHTTPクライアント4.3.4を使用してHTTP POST)のOutputStreamインターフェイスを提供します。
発信コードは次のようになります。
// 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コードは、OutputStreamと直接インラインではなく、bootstrap/initおよびfinalizationコードに存在する可能性があります。インスタンス化。