01|网络基础(Servlet 的根基)
1️⃣ HTTP 是什么
Servlet 本质就是:用 Java 写的 HTTP 请求处理程序。
HTTP 核心模型:
客户端(浏览器)
↓ 请求(Request)
服务器(Tomcat + Servlet)
↑ 响应(Response)
2️⃣ HTTP 请求的组成
GET /login?name=tom HTTP/1.1
Host: localhost:8080
Cookie: JSESSIONID=xxx
请求体(POST 才有)
关键点:
- 请求行:方法 + URL
- 请求头:浏览器信息、Cookie
- 请求体:POST 参数 / JSON
3️⃣ HTTP 响应
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
<html>...</html>
Servlet 做的事情就是:
读取请求 → 业务处理 → 写响应
02|Tomcat 安装(Servlet 的运行环境)
1️⃣ Tomcat 是什么
- Web 服务器 + Servlet 容器
- 负责:
- 监听端口(8080)
- 解析 HTTP
- 调用 Servlet
2️⃣ 安装步骤(Mac / Linux / Windows 类似)
官网下载 apache-tomcat-9.x.zip
解压
bin/startup.sh(或 startup.bat)
访问:
http://localhost:8080
3️⃣ 目录结构重点
bin/ 启动脚本
conf/ server.xml / web.xml
webapps/ 部署的项目
logs/ 日志
03|Servlet 配置(Servlet 如何被访问)
方式一:web.xml(传统)
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>com.demo.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
方式二:注解(推荐)
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}
📌 URL → Servlet 映射关系
04|Servlet 生命周期(非常重要)
生命周期流程
实例化
↓
init() (只执行一次)
↓
service() (每次请求)
↓
destroy() (服务器关闭)
示例
@Override
public void init() {
System.out.println("Servlet 初始化");
}
@Override
protected void doGet(...) {
System.out.println("处理请求");
}
@Override
public void destroy() {
System.out.println("Servlet 销毁");
}
⚠️ 重点:
- Servlet 是单例
- 不要用成员变量存请求数据(线程不安全)
05|请求和响应(HttpServletRequest / Response)
1️⃣ 获取请求参数
String name = request.getParameter("name");
2️⃣ 请求对象能做什么
- 参数
- 请求头
- Cookie
- Session
- 请求域(request.setAttribute)
3️⃣ 响应对象
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("Hello");
06|转发和重定向(高频面试点)
转发(Forward)
request.getRequestDispatcher("/jsp/success.jsp")
.forward(request, response);
特点:
- 服务器内部
- 地址栏不变
- 共享 request
重定向(Redirect)
response.sendRedirect("/login");
特点:
- 浏览器再次请求
- 地址栏改变
- request 不共享
📌 登录成功 → 重定向
📌 表单校验失败 → 转发
07|过滤器(Filter)
1️⃣ 作用
在 请求到达 Servlet 之前 / 响应返回之前 做处理
常见用途:
- 登录校验
- 编码设置
- 权限控制
- 日志
2️⃣ 示例
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) {
req.setCharacterEncoding("UTF-8");
chain.doFilter(req, res);
}
}
3️⃣ 执行链
Filter1 → Filter2 → Servlet → Filter2 → Filter1
08|监听器(Listener)
监听什么?
- ServletContext
- Session
- Request
常用监听器
| 监听器 | 作用 |
|---|---|
| ServletContextListener | 项目启动/关闭 |
| HttpSessionListener | Session 创建/销毁 |
| HttpSessionAttributeListener | Session 属性变化 |
示例
@WebListener
public class AppListener implements ServletContextListener {
public void contextInitialized(...) {
System.out.println("项目启动");
}
}
📌 常用于:
- 初始化配置
- 连接池
- 缓存预热
09|Cookie 和 Session(状态保持)
HTTP 是无状态的 ❌
Cookie / Session 用来 记住用户
Cookie(客户端)
Cookie c = new Cookie("token", "123");
c.setMaxAge(3600);
response.addCookie(c);
特点:
- 存在浏览器
- 不安全
- 有大小限制
Session(服务器)
HttpSession session = request.getSession();
session.setAttribute("user", user);
特点:
- 安全
- 基于 Cookie(JSESSIONID)
- 超时销毁
📌 登录系统 = Session
10|JSP(Servlet 的表现层)
JSP 本质是什么?
JSP = Servlet
<%= request.getAttribute("msg") %>
JSP 执行过程
.jsp → 翻译成 Servlet → 编译 → 执行
MVC 中的位置
Servlet(Controller)
JSP(View)
JavaBean(Model)
⚠️ 现代项目:
- JSP 用得少
- 被 Thymeleaf / Vue 取代
11|项目部署
1️⃣ 传统 war 包
mvn clean package
xxx.war → tomcat/webapps/
访问:
http://localhost:8080/项目名
2️⃣ ROOT 项目
ROOT.war
http://localhost:8080/
3️⃣ 生产环境建议
- Nginx + Tomcat
- HTTPS
- 日志切割
- JVM 参数
🎯 一张整体关系图(非常重要)
浏览器
↓ HTTP
Tomcat
↓
Filter
↓
Servlet
↓
Service / DAO
↓
JSP / JSON
从 Servlet 到 Spring MVC
一句话先给结论:
Spring MVC = 在 Servlet 之上的一套“更高级的 Web 编程模型”
一、整体关系(先立世界观)
浏览器
↓ HTTP
Tomcat
↓
DispatcherServlet ← Spring MVC 的核心(它本身就是 Servlet)
↓
Controller
↓
Service / DAO
↓
View (JSP / Thymeleaf / JSON)
📌 Spring MVC 并没有绕开 Servlet,而是“封装 + 扩展”它
二、核心对照表(重点)
| 对比维度 | 原生 Servlet | Spring MVC |
|---|---|---|
| 入口 | 每个 Servlet 一个入口 | 统一入口 DispatcherServlet |
| URL 映射 | web.xml / @WebServlet | @RequestMapping |
| 请求参数 | request.getParameter | @RequestParam / 自动绑定 |
| 返回响应 | response.getWriter | 返回对象 / 视图名 |
| 转发重定向 | 手写 forward / redirect | return "redirect:/xx" |
| JSON | 手动写 | @ResponseBody 自动序列化 |
| 过滤器 | Filter | Filter + Interceptor |
| 生命周期 | Servlet 生命周期 | Bean 生命周期 |
| 依赖管理 | 自己 new | IoC 自动注入 |
| 测试 | 困难 | 非常友好 |
三、入口设计对比(最本质差异)
1️⃣ Servlet:多入口、分散
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(...) {
// 登录逻辑
}
}
问题:
- Servlet 越多,入口越乱
- 通用逻辑(鉴权、日志)重复
2️⃣ Spring MVC:单入口(前端控制器模式)
public class DispatcherServlet extends HttpServlet {
// Spring 内部
}
所有请求 → DispatcherServlet → Controller
优点:
- 统一拦截
- 易扩展
- 符合大型项目
📌 这是经典 Front Controller(前端控制器)模式
四、URL 映射对比
Servlet
@WebServlet("/user/add")
public class UserAddServlet {}
Spring MVC
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/add")
public User add(User user) {}
}
✅ Spring MVC 支持:
- 类级别 + 方法级别映射
- REST 风格
- HTTP 方法语义
五、请求参数处理(差距最大)
Servlet(手动解析)
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
❌ 问题:
- 类型转换
- 空值校验
- 重复代码
Spring MVC(自动绑定)
@PostMapping("/add")
public User add(@RequestParam String name,
@RequestParam int age) {
}
甚至:
public User add(User user) {}
✅ Spring MVC 自动做了:
- 参数提取
- 类型转换
- 对象封装
- 校验(@Valid)
六、响应处理对比
Servlet
response.setContentType("application/json");
response.getWriter().write(json);
Spring MVC
@GetMapping("/user")
@ResponseBody
public User getUser() {
return user;
}
Spring MVC 自动:
- 调用 Jackson
- 转 JSON
- 设置响应头
📌 你只关心业务对象,不关心 HTTP 细节
七、转发 & 重定向
Servlet
request.getRequestDispatcher("/success.jsp")
.forward(request, response);
response.sendRedirect("/login");
Spring MVC
return "success"; // 转发
return "redirect:/login"; // 重定向
语义更清晰、代码更干净
八、过滤 vs 拦截(非常经典)
Servlet Filter(低层)
请求 → Filter → Servlet
- 对所有 Servlet 生效
- 处理编码、跨域
Spring Interceptor(高层)
DispatcherServlet
→ Interceptor
→ Controller
public class AuthInterceptor implements HandlerInterceptor {
boolean preHandle(...) {}
}
适合:
- 登录校验
- 权限控制
- 业务拦截
📌 Filter 偏基础设施,Interceptor 偏业务
九、依赖管理(本质飞跃)
Servlet
UserService service = new UserServiceImpl();
❌ 强耦合、难测试
Spring MVC
@Autowired
UserService userService;
✅ IoC:
- 解耦
- 易扩展
- 易 Mock
十、异常处理对比
Servlet
try {
} catch (Exception e) {
response.sendError(500);
}
Spring MVC
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result error() {}
}
📌 统一异常出口 = 大型系统必备
十一、为什么说:Spring MVC 是“更现代的 Servlet”?
| Servlet 能做 | Spring MVC |
|---|---|
| 能 | ✅ |
| 更优雅 | ✅ |
| 更安全 | ✅ |
| 更适合复杂系统 | ✅ |
| 更易维护 | ✅ |
👉 Servlet 是“工具”,Spring MVC 是“体系”
十二、学习路线建议(非常重要)
你可以按这个思路理解:
Servlet
↓(理解 HTTP)
Filter / Listener
↓
Spring MVC
↓
Spring Boot
📌 Spring Boot 本质 = 自动配置的 Spring MVC + 内嵌 Tomcat
正文完
