- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
当向网页发出请求并通过 servlet(通过 tomcat 处理)进行处理时,一旦您进入 servlet 级别(或 spring mvc Controller )的处理,就会拥有整个请求 header / body /等已经从客户端发送到服务器了吗?
假设客户端正在对网页执行 http POST,并且该帖子包含分配的表单元素。
所有这些数据是否会通过 tomcat 和您正在执行的 servlet,或者如果您实际上没有引用:
request.getParamater("abc")
那么你不会产生额外的负载,因为它不会被流式传输?
最佳答案
我找不到引用,但我相信一旦整个 header 可用(所有请求 header 后跟两个换行符),servlet 就会开始处理。这就是为什么你有 getInputStream()
和 getReader()
而不是 getBody()
返回 String
或 字节[]
.
这样,servlet 可以在客户端仍在发送请求数据时开始处理请求数据,从而允许 servlet 以较小的内存占用处理大量数据。比如upload servlet可以逐字节读取上传的文件并保存到磁盘,而不需要同时在内存中有完整的请求内容。
这是我用于测试的 servlet(在 Scala 中,对此感到抱歉):
@WebServlet(Array("/upload"))
class UploadServlet extends HttpServlet {
@Override
override def doPost(request: HttpServletRequest, response: HttpServletResponse) {
println(request.getParameter("name"));
val input = Source.fromInputStream(request.getInputStream)
input.getLines() foreach println
println("Done")
}
}
现在我使用 nc
模拟慢客户端:
$ nc localhost 8080
服务器端什么也没有发生。我现在手动发送一些 HTTP header :
POST /upload?name=foo HTTP/1.1
Host: localhost:8080
Content-Length: 10000000
服务器端仍然没有任何反应。 Tomcat 接受了连接,但尚未调用 UploadServlet.doPost
。但是当我点击 Enter 两次时,servlet 会打印 name
参数,但会在 getLines()
(getInputStream()
下面)。
我现在可以使用 nc
发送文本行(Tomcat 需要 10000000
字节),并且它们会逐渐打印在服务器端(input.getLines()
返回一个 Iterator[String]
阻塞直到有新行可用)。
Tomcat 在开始处理请求之前等待 整个 HTTP header (将其传递给匹配的 servlet)
请求正文不必在 doPost()
调用之前完全可用。这很好,否则我们很快就会耗尽内存。
这同样适用于发送响应 - 我们可以逐步执行此操作。
使用 Spring MVC,您必须小心。考虑以下两种方法(注意不同的参数类型):
@Controller
@RequestMapping(value = Array("/upload"))
class UploadController {
@RequestMapping(value = Array("/good"), method = Array(POST))
@ResponseStatus(HttpStatus.NO_CONTENT)
def goodUpload(body: InputStream) {
//...
}
@RequestMapping(value = Array("/bad"), method = Array(POST))
@ResponseStatus(HttpStatus.NO_CONTENT)
def badUpload(@RequestBody body: Array[Byte]) {
//...
}
}
输入 /upload/good
将在收到 HTTP header 后立即调用 goodUpload
处理程序方法,但如果您尝试读取 body
InputStream
如果还没有收到正文。
然而,/upload/bad
将等到整个 POST
正文可用,因为我们已将整个正文明确请求为字节数组(String
会产生同样的效果):@RequestBody body: Array[Byte]
.
因此,Spring MVC 如何处理大型请求体取决于您。
请记住,HTTP 在 TCP/IP 之上工作。仅仅因为您没有调用 getInputStream()
/getReader()
并不意味着服务器没有从客户端接收数据。事实上,操作系统管理网络套接字并不断接收 TCP/IP 数据包,这些数据包没有被消费。这意味着来自客户端的数据被推送到服务器,但操作系统必须缓冲该数据。
也许更有经验的人可以回答在这种情况下发生的事情(对于本网站来说,这并不是一个真正的问题)。如果服务器没有读取传入的数据,O/S 可能会突然关闭套接字,或者如果缓冲区变大,它可能会简单地缓冲它并交换?另一种解决方案可能是停止确认客户端数据包,从而导致客户端减速/停止。真的取决于操作系统,而不是 HTTP/servlet。
关于java - 当一个请求由一个 servlet 处理时,是整个请求头/正文/等。已经加载了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8733268/
我有一个关于 Java Servlet 的问题。 假设我在 servlet 网页“somePage”上。我想登录(使用另一个 servlet,“登录”servlet)。所以我点击“somePage”上
如何将变量数组从一个 servlet 传递到另一个 servlet? 最佳答案 如果您要将当前请求传递给另一个servlet,则只需将其设置为请求属性即可。 request.setAttribute(
什么可能导致此错误? Caused by: jakarta.servlet.UnavailableException: Servlet class org.restlet.ext.servle
我的maven依赖树是这样的 我想问我maven如何解决这个冲突,有两个servlet-api.jar?提前谢谢你。 最佳答案 如果您想从 Velocity 工具中删除 servlet-api,您可以
config ProcessReg ProcessReg text HelloWorld1 public class config implements Serv
您好,我有一个关于 servlet 调用另一个 servlet 的问题 我有一个名为 Relay 的主 servlet,它将负责控制其他 servlet 用户将点击并将转发到 Relay servle
在我的 REST API 项目中,我已将 /* 映射到 RESTServlet,并且需要在同一 WAR 中托管静态内容。我更愿意将 /static/* 映射到 WAS liberty 提供的默认 se
响应映射在 Servlet 中如何工作? 每个响应如何知道清除特定 HTML 或 Handlebars 上的输出? 最佳答案 有一个 ember-java带有 Jersey REST 服务 的 git
有一个 @WebServlet(urlPatterns = "/myServlet/") .如果用户转到 myapp/myServlet/other ,我仍然希望我的 servlet 能够捕获。也就是
我正在使用 Filter 在我的所有页面中插入反点击劫持 header - 这工作正常,除了 JBoss EAP 6.3 容器管理的登录页面,这是更重要的页面之一拥有它。 登录页面根本不调用过滤器,登
我正在尝试使用 RequestDispatcher 将数据从一个 servlet 传递到另一个 servlet。这是我的调度程序代码。 String address; address = "/Java
我刚刚开始使用 Servlet,并设法让一些 Servlet 充当单独的 URL,用于填充数据库以进行一些虚拟测试。某种形式: public class Populate_ServletName ex
我是否需要同时配置app.servlet.version 和 grails.servlet.version? 前者在application.properties中,后者在BuildConfig.gro
在Myeclipse中我创建了一个名为web1的Web项目,并添加了一个名为servlet1的servlet,web.xml如下: servlet1 servlet1
这个问题在这里已经有了答案: How to run a background task in a servlet based web application? (5 个回答) 6年前关闭。 是否可以在
在我的 ManagedBean 中,如果我将范围从 @RequestScoped 更改为 @ViewScoped,我将收到以下错误堆栈。我该如何解决这个问题?不过,当我运行应用程序时,我可以在页面中看
这个问题已经有答案了: How do I execute multiple servlets in sequence? (2 个回答) 已关闭 3 年前。 我已经构建了jdbc-Servlet的代码,
我一直在徒劳地尝试实现 tomcat 9 的 jakarta servlet,而不是以前的 javax.servlet 实现(因为我的理解是 jakarta 包是前进的方向)。问题是,当我将浏览器指向
我是 Spring 新手,正在尝试使用 Maven 部署和运行我的第一个 Spring Web 应用程序。有关更多详细信息,请参阅 here (我昨天发布的一个问题): 现在,我遇到的问题是:当我尝试
我正在尝试学习如何使用 JSP。我遇到了一些毫无意义的事情,至少在我看来是这样: 当我尝试运行时: response.getWriter().println(m.getDb().printAll())
我是一名优秀的程序员,十分优秀!