Commons FileUpload 很好,但在您的情况下还不够。在提供文件项(和流)之前,它将解析内存中的整个正文。您对单个项目不感兴趣。您基本上只想将请求正文从一侧透明地流式传输到另一侧,而无需以任何方式更改或将其存储在内存中。FileUpload 只会将请求主体解析为一些“可用”的 Java 对象,而 HttpClient 只会基于这些 Java 对象再次创建相同的请求主体。这些 Java 对象也会消耗内存。
您不需要为此使用库(或者它必须是Commons IOfor
才能用 oneliner替换循环IOUtils#copy()
)。只需基本的 Java NET 和 IO API 就足够了。这是一个启动示例:
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.
}