我正在处理在 JBoss-4.2.3.GA 下部署的基于 Spring MVC 的应用程序,并且想要澄清 servlet 输入/输出流如何处理巨大的请求/响应主体。我对此很烦恼,因为不想将整个请求/响应保留在内存中,直到调用完全完成。
如何准确检测 JBoss 传递给 servlet 的输入/输出流实现?或者我可以在某种规范中调查它的行为?
感谢您提供任何有用的信息。
最佳答案
默认情况下,Servlet API 不会将整个请求和响应正文保留在内存中。它实际上是您自己的处理/解析代码来完成此操作。
对于请求体,在处理它时,不应该将整个请求体保存在byte[]
中。是的,byte[]
的每个字节都会消耗 Java 内存的一个字节。您应该尝试(重新)编写代码,使其永远不会将整个主体保留在内存中。例如逐行或逐个缓冲区处理它和/或立即将其流式传输到OutputStream
。
例如当正文基于角色时:
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(someOutputStream, "UTF-8"));
for (String line; (line = reader.readLine()) != null;) {
processIfNecessary(line);
writer.writeln(line);
}
或者当主体是基于字节时:
BufferedInputStream input = new BufferedInputStream(request.getInputStream());
BufferedOutputStream output = new BufferedOutputStream(someOutputStream);
byte[] buffer = new byte[1024]; // 1KB buffer.
for (int length; (length = input.read(buffer)) > 0;) {
processIfNecessary(buffer);
output.write(buffer, 0, length);
}
对于响应体,它将保留在内存中直到达到缓冲区大小。任何超出缓冲区大小的内容都将被刷新。默认缓冲区大小通常为 2KB。这可以在应用程序服务器级别和 ServletResponse#setBufferSize()
进行配置。 。当您将缓冲区大小设置得太高时,它会占用内存。
关于java - JBoss 输入/输出流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5502321/