目录
[一、Web 项目基础结构 ★](#一、Web 项目基础结构 ★)
[二、Servlet 基础 ★★★](#二、Servlet 基础 ★★★)
[2.1 什么是 Servlet](#2.1 什么是 Servlet)
[2.2 Servlet 继承关系](#2.2 Servlet 继承关系)
[2.3 Servlet 生命周期 ★★★](#2.3 Servlet 生命周期 ★★★)
[2.4 doGet 与 doPost ★★](#2.4 doGet 与 doPost ★★)
[三、Servlet 配置方式 ★★](#三、Servlet 配置方式 ★★)
[3.1 web.xml 配置方式(传统方式)](#3.1 web.xml 配置方式(传统方式))
[3.2 注解配置方式](#3.2 注解配置方式)
[四、请求与响应对象 ★★★](#四、请求与响应对象 ★★★)
[4.1 HttpServletRequest(请求对象)](#4.1 HttpServletRequest(请求对象))
[4.2 HttpServletResponse(响应对象)](#4.2 HttpServletResponse(响应对象))
[4.3 请求参数的中文乱码问题 ★★★](#4.3 请求参数的中文乱码问题 ★★★)
[五、四大作用域 ★★★](#五、四大作用域 ★★★)
[操作方法(统一的 API):](#操作方法(统一的 API):)
[六、请求转发与重定向 ★★★](#六、请求转发与重定向 ★★★)
[6.1 请求转发(Forward)](#6.1 请求转发(Forward))
[6.2 重定向(Redirect)](#6.2 重定向(Redirect))
[6.3 对比 ★★★](#6.3 对比 ★★★)
[七、JSP 基础 ★★★](#七、JSP 基础 ★★★)
[7.1 JSP 是什么](#7.1 JSP 是什么)
[7.2 JSP 执行过程](#7.2 JSP 执行过程)
[7.3 JSP 三种脚本元素 ★★★](#7.3 JSP 三种脚本元素 ★★★)
[7.4 JSP 指令 ★★](#7.4 JSP 指令 ★★)
[7.5 JSP 隐式对象 ★★★](#7.5 JSP 隐式对象 ★★★)
[7.6 JSP 动作(Action) ★](#7.6 JSP 动作(Action) ★)
[八、会话管理 ★★★](#八、会话管理 ★★★)
[8.1 Cookie](#8.1 Cookie)
[8.2 HttpSession](#8.2 HttpSession)
[8.3 Cookie vs Session 对比 ★★★](#8.3 Cookie vs Session 对比 ★★★)
[九、Filter 过滤器 ★★★](#九、Filter 过滤器 ★★★)
[9.1 什么是 Filter](#9.1 什么是 Filter)
[9.2 Filter 生命周期](#9.2 Filter 生命周期)
[9.3 Filter 接口](#9.3 Filter 接口)
[9.4 web.xml 中配置 Filter](#9.4 web.xml 中配置 Filter)
[9.5 Filter 执行顺序](#9.5 Filter 执行顺序)
[9.6 Filter vs Servlet 对比](#9.6 Filter vs Servlet 对比)
[十、初始化参数 ★★](#十、初始化参数 ★★)
[10.1 两种初始化参数](#10.1 两种初始化参数)
[十一、EL 表达式与 JSTL(补充考点)](#十一、EL 表达式与 JSTL(补充考点))
[11.1 EL 表达式 ★](#11.1 EL 表达式 ★)
[11.2 JSTL 核心标签 ★](#11.2 JSTL 核心标签 ★)
[十二、Servlet 与 JSP 协作(MVC 模式)★★](#十二、Servlet 与 JSP 协作(MVC 模式)★★)
[12.1 MVC 架构](#12.1 MVC 架构)
[12.2 项目中的 MVC 示例](#12.2 项目中的 MVC 示例)
[十三、HTTP 状态码(补充)](#十三、HTTP 状态码(补充))
[题型 1:选择题/判断题](#题型 1:选择题/判断题)
[题型 2:填空题](#题型 2:填空题)
[题型 3:简答题](#题型 3:简答题)
[题型 4:编程题](#题型 4:编程题)
[Forward vs Redirect](#Forward vs Redirect)
[Servlet 生命周期](#Servlet 生命周期)
基于 ServletHomework 项目整理,覆盖所有可能考到的知识点。 标注 ★ 为高频考点
一、Web 项目基础结构 ★
ServletHomework/
├── pom.xml # Maven 配置
└── src/main/
├── java/com/homework/ # Java Servlet 代码
│ ├── ParamServlet.java
│ ├── EncodingFilter.java
│ └── ...
└── webapp/ # Web 资源目录
├── *.jsp # JSP 页面
├── 1.html # 静态 HTML
└── WEB-INF/
└── web.xml # 部署描述符(核心配置文件)
关键点:
WEB-INF/web.xml是 Web 应用的核心配置文件,叫部署描述符(Deployment Descriptor)WEB-INF下的资源不能被浏览器直接访问- 打包方式为 WAR(Web Application Archive)
二、Servlet 基础 ★★★
2.1 什么是 Servlet
Servlet 是运行在服务器端的 Java 程序,用于处理 HTTP 请求并生成响应。
2.2 Servlet 继承关系
Servlet (接口)
└── GenericServlet (抽象类,通用)
└── HttpServlet (抽象类,HTTP专用) ★
└── 你写的 Servlet(如 ParamServlet)
考试常考: 写 Servlet 继承 HttpServlet,不是直接实现 Servlet 接口。
2.3 Servlet 生命周期 ★★★
加载和实例化 → init() → service() → [doGet/doPost] → destroy()
| 阶段 | 方法 | 调用次数 | 说明 |
|---|---|---|---|
| 初始化 | init() |
1次 | Servlet 被创建时调用,用于初始化资源 |
| 处理请求 | service() |
每次请求 | 容器调用,自动分发到 doGet/doPost |
| 销毁 | destroy() |
1次 | Servlet 被销毁前调用,释放资源 |
✅ 项目示例 --- HelloServlet.java:
public class HelloServlet extends HttpServlet {
private String message;
public void init() { // ★ 初始化
message = "Hello World!";
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
// 处理 GET 请求
}
public void destroy() { // ★ 销毁
// 清理资源
}
}
✅ 项目示例 --- HistoryServlet.java:
public void init() throws ServletException {
// 在 init 中初始化数据库表
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE IF NOT EXISTS history (...)");
}
}
2.4 doGet 与 doPost ★★
| 方法 | 对应 HTTP | 数据位置 | 数据长度限制 | 安全性 |
|---|---|---|---|---|
doGet() |
GET | URL 查询字符串 | 有限制(约2KB) | 数据在URL中可见 |
doPost() |
POST | 请求体(Body) | 无限制 | 相对安全 |
✅ 项目示例 --- ParamServlet.java(doPost 委托给 doGet):
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
// 核心逻辑写在这里
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
doGet(req, resp); // ★ 让 doPost 调用 doGet,避免重复代码
}
三、Servlet 配置方式 ★★
3.1 web.xml 配置方式(传统方式) ✅
<!-- 1. 声明 Servlet -->
<servlet>
<servlet-name>ParamServlet</servlet-name>
<servlet-class>com.homework.ParamServlet</servlet-class>
<!-- Servlet 级别的初始化参数 -->
<init-param>
<param-name>initStuId</param-name>
<param-value>2024001001</param-value>
</init-param>
</servlet>
<!-- 2. 映射 URL -->
<servlet-mapping>
<servlet-name>ParamServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
考试常考: <servlet> 和 <servlet-mapping> 是分开配置的,通过 <servlet-name> 关联。
3.2 注解配置方式 ✅
@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet { ... }
两种方式对比:
| 特性 | web.xml | @WebServlet 注解 |
|---|---|---|
| 配置位置 | 集中在 XML 文件 | 分散在 Java 类上 |
| 修改是否需要重编译 | 不需要 | 需要 |
| 适合场景 | 需要统一管理 | 简单快速开发 |
四、请求与响应对象 ★★★
4.1 HttpServletRequest(请求对象)
常用方法一览:
| 方法 | 返回值 | 作用 | ✅ 项目示例 |
|---|---|---|---|
getParameter(name) |
String | 获取表单参数(单值) | FormHandlerServlet |
getParameterValues(name) |
String[] | 获取表单参数(多值,如复选框) | FormHandlerServlet |
setAttribute(name, obj) |
void | 设置请求域属性 | ListForwardServlet |
getAttribute(name) |
Object | 获取请求域属性 | ListShowServlet |
getSession() |
HttpSession | 获取会话对象 | LoginServlet |
getCookies() |
Cookie[] | 获取所有 Cookie | VisitTimeServlet |
setCharacterEncoding(enc) |
void | 设置请求编码 | EncodingFilter |
getCharacterEncoding() |
String | 获取请求编码 | EncodingTestServlet |
getContextPath() |
String | 获取应用上下文路径 | VisitTimeServlet |
getPathInfo() |
String | 获取 URL 路径信息 | MiniMaxProxyServlet |
getQueryString() |
String | 获取查询字符串 | MiniMaxProxyServlet |
getReader() |
BufferedReader | 读取请求体(字符流) | HistoryServlet |
getRequestDispatcher(path) |
RequestDispatcher | 获取转发器 | ListForwardServlet |
4.2 HttpServletResponse(响应对象)
| 方法 | 作用 | ✅ 项目示例 |
|---|---|---|
setContentType(type) |
设置响应内容类型 | 几乎所有 Servlet |
setCharacterEncoding(enc) |
设置响应编码 | EncodingFilter |
getWriter() |
获取字符输出流 | 几乎所有 Servlet |
sendRedirect(url) |
重定向(302) | LoginServlet |
addCookie(cookie) |
添加 Cookie | VisitTimeServlet |
setStatus(code) |
设置 HTTP 状态码 | HistoryServlet |
⚠️ 重要区分 --- getWriter() vs getOutputStream():
getWriter()--- 输出文本内容(HTML、JSON 等)getOutputStream()--- 输出二进制内容(图片、文件下载等)
4.3 请求参数的中文乱码问题 ★★★
这是考试高频考点!
| 请求方式 | 解决方法 |
|---|---|
| POST 请求 | request.setCharacterEncoding("UTF-8") |
| GET 请求 | 修改 Tomcat 的 server.xml 中 URIEncoding="UTF-8",或手动转码 |
✅ 项目方案 --- 使用 Filter 统一处理(推荐做法):
// EncodingFilter.java --- 在 Filter 中统一设置
request.setCharacterEncoding(encoding); // 请求编码
response.setCharacterEncoding(encoding); // 响应编码
response.setContentType("text/html;charset=" + encoding);
五、四大作用域 ★★★
Servlet 中有 4 个"作用域"对象,用来在不同范围内存取数据:
| 作用域 | 对象 | 生命周期 | 访问范围 | ✅ 项目示例 |
|---|---|---|---|---|
| 页面域 | pageContext |
当前页面 | 当前 JSP 页面 | 未使用 |
| 请求域 ★ | request |
一次请求 | 同一请求链(forward 有效) | ListForwardServlet → ListShowServlet |
| 会话域 ★★ | session |
一次会话 | 同一用户的所有请求 | LoginServlet 存 username,success.jsp 读取 |
| 应用域 ★★ | ServletContext |
应用启动到关闭 | 所有用户的所有请求 | StoreServlet/GetServlet、IncrementServlet |
操作方法(统一的 API):
// 存数据
xxx.setAttribute("key", value);
// 取数据
Object val = xxx.getAttribute("key");
// 删数据
xxx.removeAttribute("key");
✅ 项目示例 --- 三种作用域对比:
// ① 请求域 --- ListForwardServlet(转发传递数据)
request.setAttribute("myList", list);
request.getRequestDispatcher("/listShow").forward(request, response);
// ② 会话域 --- LoginServlet(登录后记住用户)
HttpSession session = request.getSession();
session.setAttribute("username", username);
response.sendRedirect("success.jsp");
// ③ 应用域 --- StoreServlet(全局共享数据)
ServletContext context = getServletContext();
context.setAttribute("stuName", "胡淇");
六、请求转发与重定向 ★★★
这是最重要的知识点之一,几乎必考!
6.1 请求转发(Forward) ✅
RequestDispatcher dispatcher = request.getRequestDispatcher("/listShow");
dispatcher.forward(request, response);
6.2 重定向(Redirect) ✅
response.sendRedirect("success.jsp");
6.3 对比 ★★★
| 特性 | 转发 (Forward) | 重定向 (Redirect) |
|---|---|---|
| 地址栏URL | 不变 ✅ | 改变 ✅ |
| 请求次数 | 1次 | 2次(第一次302,第二次新请求) |
| request 域数据 | 保留 ✅ | 丢失 ✅ |
| 是否经过客户端 | 不经过,服务器内部完成 | 经过客户端浏览器 |
| 能否跳到外部网站 | 不能 | 能 |
| 执行方 | 服务器 | 浏览器 |
| 效率 | 较高 | 较低 |
| API | RequestDispatcher.forward() |
response.sendRedirect() |
✅ 项目对比:
转发示例:ListForwardServlet → ListShowServlet
- request.setAttribute("myList", list); // 存数据
- dispatcher.forward(req, resp); // 转发
- ListShowServlet 中 request.getAttribute("myList") 能取到 ✅
重定向示例:LoginServlet → success.jsp
- session.setAttribute("username", name); // 存到 session
- response.sendRedirect("success.jsp"); // 重定向
- request 域数据丢失,所以必须用 session 存 ✅
七、JSP 基础 ★★★
7.1 JSP 是什么
JSP(JavaServer Pages)= HTML + Java 代码。本质是一个 Servlet,容器会把 JSP 编译成 Servlet 类。
7.2 JSP 执行过程
浏览器请求 .jsp → 容器将 JSP 编译成 .java (Servlet) → 编译成 .class → 执行 → 返回 HTML
考试常考:JSP 本质就是 Servlet!
7.3 JSP 三种脚本元素 ★★★
| 语法 | 名称 | 作用 | ✅ 项目示例 |
|---|---|---|---|
<%! ... %> |
声明 | 定义成员变量/方法 | 未使用 |
<% ... %> |
脚本段 | 编写 Java 代码 | calculate.jsp, data.jsp |
<%= ... %> |
表达式 | 输出值到页面 | index.jsp, data.jsp |
✅ 项目示例 --- calculate.jsp:
<%-- 脚本段:Java 代码 --%>
<%
String num1Str = request.getParameter("num1");
int num1 = Integer.parseInt(num1Str);
int sum = 0;
for (int i = start; i <= end; i++) {
sum += i;
}
%>
<%-- 表达式:输出结果 --%>
<p>两个整数是:<%= num1 %> 和 <%= num2 %></p>
<p>和为:<%= sum %></p>
✅ 项目示例 --- data.jsp(嵌套循环生成表格):
<% for (int i = 1; i <= n; i++) { %>
<tr>
<% for (int j = 1; j <= n; j++) { %>
<% if (i >= j) { %>
<td><%= i * j %></td>
<% } else { %>
<td></td>
<% } %>
<% } %>
</tr>
<% } %>
7.4 JSP 指令 ★★
指令用于设置 JSP 页面的全局属性。
| 指令 | 作用 | 语法 |
|---|---|---|
page |
页面属性(编码、语言、导入包等) | <%@ page ... %> |
include |
静态包含其他文件 | <%@ include file="..." %> |
taglib |
引入标签库(如 JSTL) | <%@ taglib uri="..." prefix="..." %> |
✅ 项目示例 --- 每个 JSP 都有的 page 指令:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
page 指令的常用属性:
| 属性 | 作用 | 示例 |
|---|---|---|
contentType |
响应的 MIME 类型和编码 | "text/html;charset=UTF-8" |
pageEncoding |
JSP 文件本身的编码 | "UTF-8" |
language |
脚本语言 | "java" |
import |
导入 Java 包 | "java.util.*" |
errorPage |
出错时跳转的页面 | "error.jsp" |
isErrorPage |
是否是错误处理页面 | "true" / "false" |
7.5 JSP 隐式对象 ★★★
JSP 中有 9 个隐式对象,可以直接使用,不需要声明:
| 隐式对象 | 类型 | 作用 | ✅ 项目使用 |
|---|---|---|---|
request |
HttpServletRequest | 请求对象 | calculate.jsp, data.jsp, success.jsp |
response |
HttpServletResponse | 响应对象 | 未直接使用 |
session |
HttpSession | 会话对象 | 未直接使用(通过 request.getSession()) |
application |
ServletContext | 应用上下文 | 未使用 |
out |
JspWriter | 输出对象 | 未直接使用 |
config |
ServletConfig | Servlet 配置 | 未使用 |
pageContext |
PageContext | 页面上下文 | 未使用 |
page |
Object (this) | 当前页面对象 | 未使用 |
exception |
Throwable | 异常对象(仅 isErrorPage=true 时可用) | 未使用 |
✅ 项目示例 --- success.jsp:
<%-- request 是隐式对象,直接使用 --%>
<p>欢迎:<%= request.getSession().getAttribute("username") %></p>
7.6 JSP 动作(Action) ★
JSP 动作用 XML 语法实现特定功能:
| 动作 | 作用 |
|---|---|
<jsp:forward page="..."/> |
请求转发 |
<jsp:include page="..."/> |
动态包含 |
<jsp:useBean id="..." class="..."/> |
创建 JavaBean 实例 |
<jsp:setProperty name="..." property="..." value="..."/> |
设置 Bean 属性 |
<jsp:getProperty name="..." property="..."/> |
获取 Bean 属性 |
<jsp:param name="..." value="..."/> |
传递参数 |
注意: 项目中未使用 JSP 动作,但考试可能考 <jsp:useBean> 相关内容。
八、会话管理 ★★★
HTTP 是无状态协议,需要会话管理来"记住"用户。
8.1 Cookie ✅
Cookie 是客户端存储的小型数据。
✅ 项目示例 --- VisitTimeServlet.java:
// 创建 Cookie
Cookie cookie = new Cookie("lastVisit",
URLEncoder.encode(lastVisitTime, "UTF-8"));
cookie.setMaxAge(7 * 24 * 60 * 60); // 7天有效期
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
// 读取 Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if ("lastVisit".equals(c.getName())) {
String value = URLDecoder.decode(c.getValue(), "UTF-8");
}
}
}
Cookie 关键知识点:
| 属性 | 说明 |
|---|---|
name/value |
键值对 |
maxAge |
有效期(秒),-1=浏览器关闭时失效,0=立即删除 |
path |
Cookie 的有效路径 |
domain |
Cookie 的有效域名 |
secure |
是否只在 HTTPS 下传输 |
httpOnly |
是否禁止 JavaScript 访问 |
8.2 HttpSession ✅
Session 是服务器端存储的会话数据。
✅ 项目示例 --- LoginServlet.java:
// 获取 Session(如果没有则创建)
HttpSession session = request.getSession();
// 存数据
session.setAttribute("username", username);
// 重定向到成功页面
response.sendRedirect("success.jsp");
✅ success.jsp 中读取 Session:
<%= request.getSession().getAttribute("username") %>
8.3 Cookie vs Session 对比 ★★★
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端(浏览器) | 服务器端 |
| 安全性 | 较低(用户可查看/修改) | 较高 |
| 数据大小 | 有限制(约4KB) | 无明显限制 |
| 服务器压力 | 无 | 有(占用服务器内存) |
| 跨页面 | 可以 | 可以 |
| 默认有效期 | 浏览器关闭时失效 | 30分钟不活动失效 |
| 实现原理 | HTTP 响应头 Set-Cookie | 基于 Cookie 中的 JSESSIONID |
九、Filter 过滤器 ★★★
9.1 什么是 Filter
Filter 是 Servlet 规范中的组件,用于在请求到达 Servlet 之前 或响应发送到客户端之前进行拦截处理。
9.2 Filter 生命周期
init() → doFilter() → [chain.doFilter() 放行] → destroy()
| 方法 | 作用 | 调用次数 |
|---|---|---|
init() |
初始化(读取配置参数) | 1次 |
doFilter() |
拦截处理 | 每次请求 |
destroy() |
销毁 | 1次 |
9.3 Filter 接口 ✅
public class EncodingFilter implements Filter {
private String encoding;
// ① 初始化:从 web.xml 读取配置参数
public void init(FilterConfig filterConfig) {
encoding = filterConfig.getInitParameter("encoding");
}
// ② 拦截处理
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType("text/html;charset=" + encoding);
chain.doFilter(request, response); // ★ 放行,继续执行
}
// ③ 销毁
public void destroy() { }
}
9.4 web.xml 中配置 Filter ✅
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.homework.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>
9.5 Filter 执行顺序
浏览器 → Filter1 → Filter2 → ... → Servlet → 响应原路返回
关键:chain.doFilter() 必须调用,否则请求不会到达 Servlet!
9.6 Filter vs Servlet 对比
| 特性 | Filter | Servlet |
|---|---|---|
| 作用 | 拦截/预处理/后处理 | 处理业务逻辑 |
| 触发条件 | URL 匹配 filter-mapping | URL 匹配 servlet-mapping |
| 是否生成响应 | 通常不直接生成 | 生成响应 |
| 典型应用 | 编码设置、登录验证、日志记录 | 业务处理 |
十、初始化参数 ★★
10.1 两种初始化参数
| 类型 | 标签 | 读取方式 | 作用范围 |
|---|---|---|---|
| 上下文参数 | <context-param> |
getServletContext().getInitParameter() |
整个应用 |
| Servlet 参数 | <init-param> |
getServletConfig().getInitParameter() |
单个 Servlet |
✅ 项目示例 --- web.xml:
<!-- 全局参数 -->
<context-param>
<param-name>stuId</param-name>
<param-value>2507240211</param-value>
</context-param>
<!-- Servlet 参数 -->
<servlet>
<servlet-name>ParamServlet</servlet-name>
<servlet-class>com.homework.ParamServlet</servlet-class>
<init-param>
<param-name>initStuId</param-name>
<param-value>2024001001</param-value>
</init-param>
</servlet>
✅ 项目示例 --- ParamServlet.java 中读取:
// 读取 Servlet 级别参数
ServletConfig config = getServletConfig();
String stuId = config.getInitParameter("initStuId");
// 读取全局参数
ServletContext context = getServletContext();
String globalId = context.getInitParameter("stuId");
十一、EL 表达式与 JSTL(补充考点)
虽然项目中未使用,但考试可能考到,需要了解。
11.1 EL 表达式 ★
EL(Expression Language)用于简化 JSP 中的数据访问。
<%-- 基本语法 --%>
${expression}
<%-- 访问请求参数 --%>
${param.username} <%-- 等价于 request.getParameter("username") --%}
<%-- 访问作用域 --%>
${sessionScope.username} <%-- 等价于 session.getAttribute("username") --%>
${requestScope.myList} <%-- 等价于 request.getAttribute("myList") --%>
${applicationScope.stuName} <%-- 等价于 application.getAttribute("stuName") --%>
<%-- 省略作用域时按顺序查找:page → request → session → application --%>
${username}
<%-- 运算 --%>
${1 + 2} <%-- 输出 3 --%>
${empty list} <%-- 判断是否为空 --%}
11.2 JSTL 核心标签 ★
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 条件判断 --%>
<c:if test="${score >= 60}">
<p>及格</p>
</c:if>
<c:choose>
<c:when test="${score >= 90}">优秀</c:when>
<c:when test="${score >= 60}">及格</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
<%-- 循环 --%>
<c:forEach items="${list}" var="item" varStatus="status">
<p>${status.index}: ${item}</p>
</c:forEach>
<%-- 输出 --%>
<c:out value="${username}" default="匿名"/>
十二、Servlet 与 JSP 协作(MVC 模式)★★
12.1 MVC 架构
View (JSP) ←── 展示数据
↑
| forward / setAttribute
|
Controller (Servlet) ←── 处理请求、调用业务逻辑
↑
|
Model (JavaBean) ←── 数据模型
12.2 项目中的 MVC 示例
1. 用户访问 /listForward(ListForwardServlet)
2. Servlet 创建数据:
List<String> list = Arrays.asList("Java", "JSP", "Servlet");
request.setAttribute("myList", list);
3. Servlet 转发到 View:
request.getRequestDispatcher("/listShow").forward(req, resp);
4. JSP/Servlet 展示数据:
List<String> list = (List<String>) request.getAttribute("myList");
十三、HTTP 状态码(补充)
| 状态码 | 含义 | 使用场景 |
|---|---|---|
| 200 | OK | 请求成功 |
| 301 | 永久重定向 | URL 永久变更 |
| 302 | 临时重定向 | response.sendRedirect() |
| 404 | Not Found | 资源不存在 |
| 500 | Internal Server Error | 服务器内部错误 |
十四、高频考试题型汇总
题型 1:选择题/判断题
- Servlet 生命周期方法调用顺序
- Forward vs Redirect 区别
- Cookie vs Session 区别
- JSP 隐式对象有哪些
<%= %>vs<% %>vs<%! %>区别
题型 2:填空题
- Servlet 生命周期三个阶段:
init()→service()→destroy() - 获取请求参数:
request.getParameter() - 获取会话:
request.getSession() - 请求转发:
request.getRequestDispatcher().forward() - 重定向:
response.sendRedirect()
题型 3:简答题
- 简述 Servlet 的生命周期
- forward 和 redirect 的区别
- Cookie 和 Session 的区别
- Filter 的作用和执行流程
- JSP 的 9 个隐式对象
- 四种作用域及其区别
题型 4:编程题
- 编写一个 Servlet 处理表单提交(参见 FormHandlerServlet)
- 编写一个 Filter 实现编码设置(参见 EncodingFilter)
- 编写 JSP 使用脚本段输出数据(参见 data.jsp)
- 实现登录功能(Session + Redirect)(参见 LoginServlet)
- 使用 RequestDispatcher 实现转发(参见 ListForwardServlet)
十五、速记口诀
Forward vs Redirect
转发地址不变,重定向地址变; 转发数据保留,重定向数据丢; 转发一次请求,重定向两次; 转发服务器做,重定向浏览器做。
四大作用域
页面最短命,请求跟转发; 会话跟用户,应用管全局。
三种脚本
声明 <%! %> 定义成员, 脚本 <% %> 写逻辑, 表达式 <%= %> 输出值。
Servlet 生命周期
init 初始化一次,service 处理每次,destroy 销毁一次。
复习建议: 先通读一遍理解框架,然后对照项目代码逐个验证每个知识点,最后做题巩固。项目中的每个 Servlet/JSP 都是真实可运行的例子,比纯理论记忆更有效。