Tomcat工作机制与Servlet流程详解
由于之前没有专门学过Tomcat,导致一直对前后端数据传输的过程不了解,最近的云图库项目正好多次用到了HttpServletRequest,就简单讲解一下Tomcat 的工作机制和 Servlet 规范。
我们举一个例子讲解整个流程:
示例场景
用户访问登录页面,输入用户名/密码后点击提交:
前端页面:http://localhost:8080/myapp/login.html
后端接口:http://localhost:8080/myapp/login (POST)
完整流程详解
第一步:前端发起请求 (浏览器)
- 用户在浏览器填写表单:
<form action="/myapp/login" method="POST"><input name="username" value="alice"><input name="password" type="password" value="p@ssw0rd"><button type="submit">登录</button></form>
- 点击提交按钮时,浏览器:
- 构造 HTTP POST 请求
- 请求行:
POST /myapp/login HTTP/1.1
- 请求头:
Host: localhost:8080Content-Type: application/x-www-form-urlencodedCookie: JSESSIONID=1234abcd (如果存在)
- 请求体:
username=alice&password=p%40ssw0rd
(URL编码)
第二步:Tomcat 接收请求 (网络层)
- Tomcat 的 NIO 线程接收 TCP 数据包
- 连接器(Http11NioProtocol)解析原始HTTP报文
- 验证Host头匹配虚拟主机配置
第三步:创建 Servlet 容器对象
Tomcat 内部创建的关键对象:
RequestFacade
(HttpServletRequest实现类)ResponseFacade
(HttpServletResponse实现类)
第四步:路由到对应 Servlet
映射规则:
- 匹配 Context Path:
/myapp
- 映射 Servlet Path:
/login
→LoginServlet.class
第五步:Servlet 处理请求 (业务逻辑)
// 后端Servlet代码示例
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) {// 1. 获取请求参数String username = request.getParameter("username"); // "alice"String password = request.getParameter("password"); // "p@ssw0rd"// 2. 业务处理(数据库验证等)UserService userService = new UserService();boolean isValid = userService.authenticate(username, password);// 3. 构造响应if(isValid) {// 设置会话HttpSession session = request.getSession();session.setAttribute("user", username);// 重定向到主页response.sendRedirect("/myapp/home");} else {// 返回错误JSONresponse.setContentType("application/json");PrintWriter out = response.getWriter();out.print("{\"error\":\"无效凭证\"}");}}
}
第六步:Tomcat 发送响应
实际发送的响应示例:
HTTP/1.1 302 Found
Location: http://localhost:8080/myapp/home
Set-Cookie: JSESSIONID=5678efgh; Path=/myapp; HttpOnly
Content-Length: 0
第七步:浏览器处理响应
- 收到302重定向响应:
- 自动发起新请求:
GET /myapp/home
- 自动发起新请求:
- 存储Cookie:
- 后续请求自动携带:
Cookie: JSESSIONID=5678efgh
- 后续请求自动携带:
- 渲染最终页面
关键对象在内存中的状态
阶段 | HttpServletRequest 内容 | HttpServletResponse 内容 |
---|---|---|
创建后 | method="POST"parameters={username:"alice",...}cookies=[...] | status=200headers={} |
Servlet处理中 | 新增:request.getSession() | 设置:status=302header[Location]="/myapp/home" |
响应前 | 所有数据冻结 | 转换为字节流 |
完整流程总结
- 前端:构造HTTP请求(含表单数据)
- Tomcat网络层:接收并解析原始字节流
- Tomcat容器:创建Request/Response对象
- 路由:根据URL映射到对应Servlet
- Servlet:执行业务逻辑(核心处理阶段)
- 响应构建:设置状态码/头信息/响应体
- Tomcat:转换对象为HTTP响应报文
- 浏览器:处理响应并渲染结果
精确表述就是:
Tomcat 是一个实现了 Java Servlet 规范的 Servlet 容器。当客户端发送一个 HTTP 请求到部署在 Tomcat 上的 Web 应用时,Tomcat 解析该请求,创建代表该请求的 HttpServletRequest
对象和代表响应的 HttpServletResponse
对象。然后,Tomcat 根据配置找到负责处理该请求的 Servlet(或 Filter 链),并调用其 service()
方法(或相应的 doXxx()
方法),将 HttpServletRequest
和 HttpServletResponse
对象作为参数传递进去。
关键点澄清:
- “后端”是谁? 在 Servlet 模型中,处理请求的核心业务逻辑(你编写的 Java 代码)就是运行在 Servlet 容器(Tomcat)内部的 Servlet。Tomcat 本身既是容器也是运行环境。所以“传递给后端”实质上是传递给容器内由你编写的特定 Servlet 实例。
- ServletRequest vs HttpServletRequest:
HttpServletRequest
是ServletRequest
的子接口,专门用于 HTTP 协议。Tomcat 创建并提供的是HttpServletRequest
对象。 - Tomcat 不止是容器: 虽然 Servlet 容器是其核心,现代的 Tomcat 也内置了一个功能完善的 HTTP Web 服务器,能够直接处理 HTTP(S) 连接。它还支持 JSP 等其他规范。
💡 关键点:Tomcat作为桥梁将原始网络请求转化为Java对象(HttpServletRequest),业务处理完成后,再将Java对象(HttpServletResponse)转化回网络响应。