Servlet 是什么?—— Java Web 的“请求处理员”
Servlet是Java Web开发的核心组件,充当浏览器与Java程序间的桥梁。它由Tomcat容器管理,负责处理HTTP请求并生成响应,开发者只需专注业务逻辑而无需处理底层协议。Servlet生命周期包含加载实例化、初始化、处理请求和销毁四个阶段,通过doGet()和doPost()方法分别处理不同类型的请求。请求处理涉及request(获取客户端数据)和response(设置服务器响应)两个
一、什么是 Servlet?(邮局比喻)
你写了一个 Java 类,里面有一个方法能返回“Hello World”。
你想让用户通过浏览器访问 http://你的电脑/hello 时看到这句话。
但是浏览器不认识你的 Java 类,它只认识 HTTP 协议。
Servlet 就是一座桥:
-
它让你的 Java 类能被浏览器通过网址访问。
-
你只需要在类里写“输出 Hello World”的代码,剩下的(接收请求、解析 HTTP、返回响应)都交给 Tomcat 去做。
邮局比喻:
你写了一封信(要输出的内容)。
邮局(Tomcat)负责把信装进信封、写地址、投递。
那封信本身,就是 Servlet 里你写的那段代码。
一句话:Servlet 是一个 Java 类,它被 Tomcat 管理,专门用来接收浏览器请求并返回响应。
二、为什么需要 Servlet?(不用它有多麻烦)
不用 Servlet,你就要自己写 Java 代码做这些事:
-
监听 8080 端口
-
解析 HTTP 请求文本(GET /hello HTTP/1.1...)
-
判断路径 /hello 该执行哪段逻辑
-
拼 HTTP 响应(状态码、响应头、响应体)
-
处理多线程并发
…… 几百行底层代码,还容易错。
有了 Servlet:
-
Tomcat 帮你做完上面所有脏活。
-
你只需要写一个类,在里面写
out.println("Hello World")。
三、Servlet 和 Tomcat 的关系
| 角色 | 负责的事 |
|---|---|
| Tomcat | 接收 HTTP 请求、解析报文、管理 Servlet 的生死、返回响应 |
| Servlet | 你写的 Java 类,里面是具体的业务逻辑(比如返回“Hello”) |
类比:
-
Tomcat 是餐厅后厨系统(接单、传菜、洗碗)。
-
Servlet 是厨师(只负责做菜)。
四、Servlet 的生命周期(它的一生)
Tomcat 会管理 Servlet 从出生到死亡的整个过程,叫做生命周期。一共四个阶段:
| 阶段 | 什么时候发生 | 做了什么事 | 调用次数 |
|---|---|---|---|
| 1. 加载与实例化 | 用户第一次访问这个 Servlet 时(或 Tomcat 启动时如果配置了 load-on-startup) | Tomcat 用 Java 反射创建这个 Servlet 的对象(也就是 new 出来) | 1 次 |
| 2. 初始化 | 实例化之后,处理请求之前 | Tomcat 调用 init() 方法。你可以在这里放一次性的准备工作(比如连接数据库) |
1 次 |
| 3. 处理请求 | 每一次用户访问 | Tomcat 调用 service() 方法,里面根据 HTTP 方法(GET/POST)自动调用 doGet() 或 doPost() |
多次 |
| 4. 销毁 | Tomcat 关闭或者你的应用被卸载时 | Tomcat 调用 destroy() 方法。你可以在这里释放资源(比如关闭数据库连接) |
1 次 |
生活类比:
-
实例化 = 招了一个新厨师(买工服、办健康证)。
-
初始化 = 厨师熟悉厨房、认灶台(一次性准备)。
-
处理请求 = 每来一个客人点菜,厨师就做一次菜。
-
销毁 = 厨师离职,结清工资、交回工服。
你不需要写
init()和destroy(),除非你想做额外的事。Tomcat 会帮你调用它们。
五、doGet 和 doPost(两种最常见的请求方式)
浏览器发请求有两种最常见的方式:GET 和 POST。
Servlet 用不同的方法来分别处理它们。
| 方法 | 浏览器何时使用 | 你在 Servlet 里写 |
|---|---|---|
| doGet() | 直接在地址栏输入网址、点击超链接、<form method="get"> |
把处理 GET 请求的代码放在这里 |
| doPost() | 表单提交且 method="post"(例如登录、注册、上传文件) | 把处理 POST 请求的代码放在这里 |
一个简单的写法:
text
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
// 处理 GET 请求(比如显示登录页面)
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
// 处理 POST 请求(比如校验用户名密码)
}
}
提示:大多数业务中,GET 用来“拿数据”,POST 用来“提交数据”。
如果你两种请求都想用同一段逻辑,可以重写service()方法,但初学分着写更清晰。如果你只写了
doPost,而浏览器发来 GET 请求,Tomcat 会返回 405 Method Not Allowed 错误。
六、两个核心对象:request 和 response
Tomcat 调用你的 doGet() 或 doPost() 时,会给你两个现成的对象:
| 对象 | 全称 | 作用 | 你能用它做什么 |
|---|---|---|---|
| request | HttpServletRequest | 装着浏览器发来的所有信息 | 获取参数、获取请求头、获取 Cookie、获取 Session |
| response | HttpServletResponse | 用来设置服务器要返回的信息 | 设置状态码、设置响应头、输出内容(HTML 或 JSON)、重定向 |
常见用法示例(不需要记住,看懂意思就行):
text
// 从 request 里拿参数
String username = request.getParameter("username");
String password = request.getParameter("password");
// 从 request 里拿请求头
String userAgent = request.getHeader("User-Agent");
// 用 response 输出内容
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<h1>欢迎你," + username + "</h1>");
// 用 response 重定向(让浏览器去另一个地址)
response.sendRedirect("/home");
类比:
request = 客人给你的点菜单(上面写着“要一份宫保鸡丁,少辣”)。
response = 你做完菜后装盘的盘子(里面是宫保鸡丁,上面还贴了标签“少辣”)。
七、转发(forward)与重定向(redirect)
当 Servlet 处理完请求后,有时需要跳到另一个页面(比如登录成功后跳到首页)。有两种方式:转发 和 重定向。
7.1 转发(Forward)
-
代码:
request.getRequestDispatcher("/home.jsp").forward(request, response); -
浏览器地址栏:不变(还是原来的 URL)
-
请求次数:1 次(服务器内部跳转)
-
request 对象:可以共享数据(用
request.setAttribute存,目标页面能取到) -
只能跳转本站内部的页面
7.2 重定向(Redirect)
-
代码:
response.sendRedirect("/home.jsp"); -
浏览器地址栏:变成新 URL
-
请求次数:2 次(第一次返回 302,浏览器再发第二次请求)
-
request 对象:不共享(两次请求是完全独立的)
-
可以跳转到任何 URL(包括其他网站)
7.3 对比表格
| 对比点 | 转发 (Forward) | 重定向 (Redirect) |
|---|---|---|
| 地址栏 | 不变 | 变成新地址 |
| 请求次数 | 1 次 | 2 次 |
| request 对象 | 共享 | 不共享 |
| 跳转范围 | 仅本站内部 | 任何 URL(站内/站外) |
| 典型使用场景 | Servlet → JSP 展示数据 | 登录成功后跳转、防止表单重复提交 |
生活类比:
-
转发 = 你在公司内部找同事办事,外人是看不到这个内部流程的。
-
重定向 = 你打客服电话,客服说“这事不归我管,你打 12345678”,你挂了电话重新拨号。
初学建议:
如果你想返回一个页面并带数据过去(比如用户信息),用 转发。
如果你想完成操作后让浏览器刷新一个新页面(比如登录成功),用 重定向(防止刷新页面重复提交表单)。
八、一个完整的用户访问流程(整合所有概念)
-
用户在浏览器输入
http://localhost:8080/myapp/login -
浏览器发送 GET 请求
-
Tomcat 解析请求,根据
@WebServlet("/login")找到LoginServlet -
Tomcat 检查这个 Servlet 是否已经实例化:
-
第一次访问 → 创建对象 → 调用
init() -
后续访问 → 直接用已有对象
-
-
Tomcat 调用
service()方法,发现是 GET 请求,于是调用你写的doGet() -
在
doGet()中:-
你用
request.getParameter(...)拿到用户名等参数 -
你调用业务逻辑(比如查数据库)
-
你用
request.setAttribute(...)存入结果 -
你用
request.getRequestDispatcher("/welcome.jsp").forward(request, response)转发到 JSP
-
-
Tomcat 执行 JSP,JSP 从 request 里取出数据,生成 HTML
-
Tomcat 把 HTML 拼成 HTTP 响应,发回浏览器
-
浏览器显示页面
如果使用了重定向,第 6 步最后会用 response.sendRedirect(...),浏览器会收到 302 状态码,然后自动发起第二次请求。
九、动手实验(配合你的 Tomcat 环境)
实验1:观察生命周期
-
在一个 Servlet 的
init()、doGet()、destroy()中都加上System.out.println("...")。 -
启动 Tomcat,第一次访问该 Servlet,观察控制台输出(你会看到
init打印一次,每次访问都打印doGet)。 -
关闭 Tomcat,看到
destroy打印。
实验2:观察 GET 和 POST
-
写一个 Servlet,同时在
doGet()和doPost()里输出不同文字。 -
用浏览器地址栏直接访问 → 触发
doGet()。 -
写一个简单的 HTML 表单,method="post",提交后触发
doPost()。
实验3:体验转发和重定向的区别
-
写两个 Servlet:
ForwardServlet和RedirectServlet。 -
分别在它们里面用
forward和sendRedirect跳转到同一个 JSP 页面。 -
观察浏览器地址栏的变化,以及刷新页面时是否有重复提交的提示。
分别访问转发和重定向的 Servlet,截图地址栏对比,然后刷新转发后的页面,浏览器会提示“是否重新提交表单”(因为刷新会重复上一次请求),而重定向后刷新不会重复提交。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)