Commons FileUpload は素晴らしいですが、あなたの場合は十分ではありません。ファイル項目 (およびストリーム) を提供する前に、メモリ内の本文全体を解析します。個々のアイテムには興味がありません。基本的には、リクエスト本文を変更したりメモリに保存したりせずに、一方から他方に透過的にストリーミングしたいだけです。FileUpload はリクエスト本文を解析して「使用可能な」Java オブジェクトにするだけで、HttpClient はそれらの Java オブジェクトに基づいてまったく同じリクエスト本文を再度作成するだけです。これらの Java オブジェクトもメモリを消費します。
これにはライブラリは必要ありません(または、を使用してループをワンライナーに置き換えるにはCommons IOでなければなりません)。基本的な Java NET と IO API だけで十分です。キックオフの例を次に示します。for
IOUtils#copy()
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URLConnection connection = new URL("http://your.url.to.panda").openConnection();
connection.setDoOutput(true); // POST.
connection.setRequestProperty("Content-Type", request.getHeader("Content-Type")); // This one is important! You may want to check other request headers and copy it as well.
// Set streaming mode, else HttpURLConnection will buffer everything.
int contentLength = request.getContentLength();
if (contentLength > -1) {
// Content length is known beforehand, so no buffering will be taken place.
((HttpURLConnection) connection).setFixedLengthStreamingMode(contentLength);
} else {
// Content length is unknown, so send in 1KB chunks (which will also be the internal buffer size).
((HttpURLConnection) connection).setChunkedStreamingMode(1024);
}
InputStream input = request.getInputStream();
OutputStream output = connection.getOutputStream();
byte[] buffer = new byte[1024]; // Uses only 1KB of memory!
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
output.flush();
}
output.close();
connection.getInputStream(); // Important! It's lazily executed.
}