12

ジャージークライアントを使用して大きなファイルをInputStreamとして配置すると、ファイルの内容全体がサーバーに送信される前にメモリにバッファリングされているように見えます。これにより、JVMのヒープスペースが不足するため、大きなファイルで問題が発生します。ジャージークライアントでこの動作を防ぐにはどうすればよいですか?サーバー側のJAX-RSリソースメソッドでは、データを送信するときにこの問題は発生しないようです。

例えば:

WebResource dataUploadResource = buildDataUploadResource();
dataUploadResource.type(getMimeType()).put(getLargeInputStream());
4

1 に答える 1

13

この動作を防ぐには、リクエストにチャンクエンコーディング1を使用するようにJerseyクライアントを構成する必要があります。これにより、Content-Lengthヘッダーを設定する必要がなくなり、コンテンツ全体をメモリにバッファリングすることなく、提供されたInputStreamからストリーミングされます。

デフォルトでは、JerseyはJDKのHttpURLConectionクラスを使用してHTTP要求と応答を処理します。残念ながら、これにはチャンクエンコーディング転送に関連するいくつかのバグがあります。幸い、Jerseyには、さまざまなHTTPクライアント実装を使用できるようにする拡張ポイントがあります。そのような実装の1つは、ApacheHttpクライアント2に基づいています。

apache htppクライアントハンドラーには2つの実装があります。1つは現在の保守終了3.xバージョンをサポートし、もう1つは新しい4.xバージョンを使用します。私たちのプロジェクトでは、古い(3.1)バージョンに基づく実装を使用しました。ライブラリは、MavenCentralの「contribs」サブグループで利用できます。

<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-apache-client</artifactId>
    <version>1.14</version>
</dependency>

次に、新しい実装を使用するために、Jerseyクライアントを初期化する必要があります。

Client jerseyClient = ApacheHttpClient.create(getClientConfig());

チャンクエンコーディングを有効にするには、デフォルトでは有効になっていないため、クライアント構成でチャンクエンコーディングサイズを設定する必要があります。

private ClientConfig getClientConfig() {
   ClientConfig config = new DefaultClientConfig();

   config.getProperties().put(
            DefaultApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, 0);
   return config;
}

このプロパティがない限りnull、チャンクエンコーディングが使用されます。実際、バージョン1.14は、サイズの指定が基盤となるapache commons(httpclientライブラリ)でサポートされていないため、エンコーディングサイズを無視します。

于 2012-06-24T10:52:29.067 に答える