Servlet & JSP 教程:从入门到实战
目录
-
第一部分:基础概念与环境搭建
(图片来源网络,侵删)- 1 什么是 Web 应用?
- 2 什么是 Servlet?
- 3 什么是 JSP?
- 4 为什么学习 Servlet & JSP?(它们的位置)
- 5 开发环境准备
- 5.1 JDK
- 5.2 Web 服务器 (Tomcat)
- 5.3 IDE (IntelliJ IDEA / Eclipse)
- 5.4 构建工具 (Maven) - 强烈推荐
-
第二部分:Servlet 核心详解
- 1 第一个 Servlet 程序 ("Hello, World!")
- 创建 Web 项目
- 编写 Servlet 类
web.xml配置 (传统方式)- 使用注解
@WebServlet(现代方式) - 部署与运行
- 2 Servlet 生命周期
init(ServletConfig)service(ServletRequest, ServletResponse)destroy()
- 3 Servlet 核心 API
HttpServletRequest: 获取请求信息 (参数、头、会话等)HttpServletResponse: 设置响应信息 (状态码、头、输出内容)
- 4 请求转发与重定向
RequestDispatcher.forward(): 服务器端行为,地址栏不变response.sendRedirect(): 客户端行为,地址栏改变
- 5 ServletContext 与会话管理
ServletContext: 应用域,整个共享的数据HttpSession: 会话域,单个用户共享的数据 (购物车案例)
- 1 第一个 Servlet 程序 ("Hello, World!")
-
第三部分:JSP 核心详解
- 1 什么是 JSP?
- 2 JSP 的三种核心元素
- 2.1 JSP 指令 (
page,include,taglib) - 2.2 JSP 动作 (
jsp:include,jsp:forward,jsp:param) - 2.3 JSP 内置对象 (9个核心对象)
- 2.1 JSP 指令 (
- 3 JSP 脚本元素
- 表达式:
<%= ... %> - 脚本片段:
<% ... %> - 声明:
<%! ... %>
- 表达式:
- 4 JSP 执行原理
JSP 如何被翻译成 Servlet
- 5 EL 表达式 (Expression Language)
- 语法:
- 作用:简化获取域中数据的代码
- 6 JSTL (JSP Standard Tag Library)
- 作用:用标签代替 Java 代码,使页面更简洁
- 常用标签:
c:if,c:forEach,fmt:formatDate等
-
第四部分:MVC 设计模式与整合
(图片来源网络,侵删)- 1 什么是 MVC?
- Model (模型): JavaBean, 业务逻辑
- View (视图): JSP, 用于展示数据
- Controller (控制器): Servlet, 接收请求,调用模型,转发到视图
- 2 为什么使用 MVC?
实现职责分离,提高代码可维护性、可重用性
- 3 一个完整的 MVC 示例:用户登录
- Model:
User.java(JavaBean),UserService.java(业务逻辑) - View:
login.jsp(登录页),welcome.jsp(欢迎页) - Controller:
LoginServlet.java
- Model:
- 1 什么是 MVC?
-
第五部分:实战项目:简易留言板
- 1 需求分析
- 2 数据库设计 (使用 MySQL + JDBC)
- 3 项目结构
- 4 功能实现
- 留言列表展示 (ListServlet + messageList.jsp)
- 发表新留言 (PostServlet + post.jsp)
- 5 代码优化与总结
-
第六部分:进阶与未来
- 1 过滤器
- 2 监听器
- 3 从 Servlet/JSP 到现代框架
- Spring MVC: 依然是 Java Web 领域的王者
- Spring Boot: 新一代标准,极大地简化了开发
第一部分:基础概念与环境搭建
1 什么是 Web 应用?
Web 应用(网络应用程序)运行在 Web 服务器上,通过浏览器(客户端)进行访问的应用程序,淘宝、京东、博客系统等。

2 什么是 Servlet?
Servlet 是运行在 Web 服务器端的 Java 小程序,它使用 Java 语言编写,遵循 Java Servlet API 规范。Servlet 的核心作用是接收和响应来自客户端(通常是浏览器)的 HTTP 请求。
你可以把它想象成 Web 服务器的一个“门卫”,所有进入服务器的 HTTP 请求都由它来处理。
3 什么是 JSP?
JSP (JavaServer Pages) 是一种动态网页技术标准,它允许开发者在 HTML 页面中嵌入 Java 代码和特定的 JSP 标签,从而创建动态生成的网页。
JSP 的本质是一个 Servlet。 当一个 JSP 页面第一次被请求时,Web 服务器会将其翻译成一个 Servlet 类,然后编译并执行,后续的请求会直接执行编译后的 Servlet,以提高性能。
比喻:
- Servlet:像一位全能的厨师,既要处理订单(逻辑),又要亲自上菜(页面展示),当页面内容复杂时,代码会变得非常混乱。
- JSP:像一位餐厅经理,他只负责看菜单(逻辑),然后把菜单交给后厨(Servlet)去做,最后由服务员(JSP)把做好的菜(HTML)端给客人,这样分工明确,代码清晰。
4 为什么学习 Servlet & JSP?
它们是 Java Web 开发的基石和经典技术。
- 理解原理:学习它们能让你深刻理解 Web 请求/响应模型、会话管理等核心概念,这些概念在任何 Web 框架中都存在。
- 面试必备:即使是现在,很多面试官仍会通过这些问题来考察你的 Java Web 基础是否扎实。
- 维护旧项目:许多遗留系统仍然在使用这些技术。
- 过渡到框架:学习 Spring MVC 等现代框架时,你会发现它们内部大量使用了 Servlet 和 JSP 的思想,掌握了基础,学习框架会事半功倍。
5 开发环境准备
- JDK: Java 开发工具包,提供 Java 运行环境和开发工具,建议使用 JDK 8 或更高版本。
- Web 服务器: 用于运行和部署 Web 应用,最常用的是 Apache Tomcat。
- 下载地址:https://tomcat.apache.org/
- 下载后解压即可使用。
- IDE: 集成开发环境,用于编写代码、调试和部署。
- IntelliJ IDEA (Ultimate 版): 功能强大,对 Java Web 支持极佳,强烈推荐。
- Eclipse: 老牌免费 IDE,需要额外安装插件来支持 Web 开发。
- 构建工具: 用于管理项目依赖(如各种 jar 包)和构建项目。
- Maven: 目前最主流的 Java 项目管理工具,强烈建议使用 Maven 来管理你的项目,它会自动下载所需的 Servlet API、JSTL 等库。
第二部分:Servlet 核心详解
1 第一个 Servlet 程序
目标: 访问一个 URL,浏览器上显示 "Hello, Servlet World!"。
步骤 (以 IntelliJ IDEA + Maven 为例):
-
创建 Maven Web 项目
File->New->Project->Maven-> 勾选Create from archetype-> 选择maven-archetype-webapp。- 输入 GroupId 和 ArtifactId,点击 Finish。
-
配置 Maven
- 确保你的
pom.xml文件中已经包含了servlet-api依赖,如果没有,手动添加:<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> <!-- provided 表示由容器(如Tomcat)提供 --> </dependency> </dependencies>
- 确保你的
-
编写 Servlet 类
- 在
src/main/java目录下创建你的包,com.example.demo。 - 在包中创建一个 Java 类,
HelloServlet。package com.example.demo;
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;
// 使用注解配置,更现代的方式 @WebServlet("/hello") public class HelloServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 设置响应内容类型和字符编码 resp.setContentType("text/html;charset=UTF-8"); // 2. 获取向客户端输出内容的 PrintWriter 对象 PrintWriter out = resp.getWriter(); // 3. 输出 HTML 内容 out.println("<html>"); out.println("<head><title>Hello Servlet</title></head>"); out.println("<body>"); out.println("<h1>Hello, Servlet World!</h1>"); out.println("</body>"); out.println("</html>"); } - 在
-
配置 Tomcat
- 在 IDEA 中,点击右上角的
Add Configuration。 - 点击 号,选择
Tomcat Server->Local。 - 在
Deployment标签页,点击 号,选择Artifact,然后选择你刚刚创建的your-artifact-name:war exploded。 - 在
Server标签页,可以设置 Tomcat 的路径和 HTTP 端口(默认 8080)。
- 在 IDEA 中,点击右上角的
-
部署与运行
- 点击 IDEA 的
Run按钮(绿色三角形)。 - 等待 Tomcat 启动成功后,在浏览器中访问:
http://localhost:8080/你的项目名/hello - 你应该能看到 "Hello, Servlet World!" 的字样。
- 点击 IDEA 的
web.xml 配置 (传统方式)
在 src/main/webapp/WEB-INF/web.xml 中配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.example.demo.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
注解 vs
web.xml:注解@WebServlet是 Servlet 3.0 引入的特性,更简洁,是当前的主流方式。web.xml是传统方式,在一些老项目中仍然可以看到。
2 Servlet 生命周期
Servlet 的生命周期由容器(Tomcat)管理,包含三个阶段:
- 初始化:当 Servlet 第一次被请求时,容器会创建它的实例,并调用
init()方法,这个方法在整个生命周期中只执行一次,通常在这里做一些一次性的初始化工作,如加载配置文件、建立数据库连接等。 - 处理请求:每次请求到达,容器都会调用
service()方法,对于 HTTP Servlet,service()方法会根据请求类型(GET, POST 等)调用相应的doGet(),doPost()等方法,这个方法可以被调用多次。 - 销毁:当 Web 应用被卸载或服务器关闭时,容器会调用
destroy()方法,这个方法也只执行一次,用于释放资源,如关闭数据库连接。
3 Servlet 核心 API
HttpServletRequest: 代表客户端的请求,你可以用它来获取:- 请求参数:
request.getParameter("username") - 请求头:
request.getHeader("User-Agent") - 请求方法:
request.getMethod() - 请求 URI:
request.getRequestURI() - 会话对象:
request.getSession()
- 请求参数:
HttpServletResponse: 代表服务器的响应,你可以用它来:- 设置响应状态码:
response.setStatus(404) - 设置响应头:
response.setHeader("Content-Type", "text/html;charset=UTF-8") - 获取输出流,向客户端写数据:
PrintWriter out = response.getWriter()或OutputStream out = response.getOutputStream()
- 设置响应状态码:
4 请求转发与重定向
这是 Web 开发中两个非常重要的概念,用于控制页面跳转。
| 特性 | 请求转发 (forward) |
重定向 (sendRedirect) |
|---|---|---|
| 行为 | 服务器端行为 | 客户端行为 |
| 地址栏 | 不变,显示的是原始请求的 URL | 改变,显示的是跳转后的新 URL |
| 请求次数 | 一次请求 | 两次请求(浏览器第一次请求,服务器响应一个 302,浏览器再发第二次请求) |
| 数据共享 | 可以共享 request 域中的数据 |
不能共享 request 域中的数据,除非通过 URL 传参或 Session |
| 使用场景 | 页面跳转,需要共享数据时 | 用户登录成功后跳转到主页,防止表单重复提交 |
示例代码:
// 在 Servlet A 中
// 1. 请求转发
request.setAttribute("msg", "这是来自A的消息");
request.getRequestDispatcher("/B").forward(request, response);
// 2. 重定向
// response.sendRedirect("/项目名/B");
5 ServletContext 与会话管理
ServletContext: 代表整个 Web 应用,它是一个应用域对象,所有用户共享。- 获取方式:
getServletContext() - 作用:获取全局配置信息 (
getInitParameter)、共享数据 (setAttribute/getAttribute)、获取资源文件路径等。
- 获取方式:
HttpSession: 代表一次用户会话,它是会话域对象,单个用户在整个浏览网站期间共享。- 获取方式:
request.getSession() - 作用:存储用户的登录信息、购物车等需要“的数据。
- 原理:服务器在创建 Session 时,会生成一个唯一的
JSESSIONID,并通过 Cookie 将其发送给客户端,之后客户端每次请求都会带上这个 ID,服务器通过 ID 找到对应的 Session 对象。
- 获取方式:
第三部分:JSP 核心详解
1 什么是 JSP?
JSP 文件的后缀是 .jsp,它看起来像是一个 HTML 文件,但其中可以嵌入 Java 代码,这使得页面能够动态地显示内容。
2 JSP 的三种核心元素
-
JSP 指令: 用于整个 JSP 页面的设置,以
<%@ ... %>开头。page: 设置页面的属性,如语言、编码、导入的包等。<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.util.List" %>
include: 在翻译阶段,将另一个文件的内容静态地包含进来。<%@ include file="header.jsp" %>
taglib: 引入标签库,如 JSTL。<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
JSP 动作: 在请求处理阶段执行的动作,以
<jsp: ...>开头。<jsp:include>: 动态包含,被包含的页面会被先编译执行,结果再包含进来。<jsp:forward>: 请求转发,将请求转发到另一个页面。<jsp:param>: 用于向被包含或转发的页面传递参数。
-
JSP 内置对象: JSP 容器自动为每个页面创建的 9 个对象,无需声明即可使用。
request,response,session,application(ServletContext),pageContext,config,out,page(当前Servlet实例),exception(错误页面)。
3 JSP 脚本元素
- 表达式:
<%= ... %>用于输出一个表达式的值到页面上。注意结尾没有分号。<h1>欢迎, <%= request.getParameter("username") %></h1> - 脚本片段:
<% ... %>可以编写任意多的 Java 语句。<% List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); for(String name : names) { %> <p><%= name %></p> <% } %> - 声明:
<%! ... %>用于声明变量或方法,会被翻译为 Servlet 类的成员。<%! private int count = 0; public int getCount() { return count++; } %> <p>访问次数: <%= getCount() %></p>
4 JSP 执行原理
当你访问一个 JSP 页面时,Tomcat 会:
- 在
work目录下创建一个对应的 Java 源文件(一个 Servlet 类)。 - 编译这个 Java 源文件生成
.class文件。 - 执行这个 Servlet 类来响应请求。
JSP 的本质就是 Servlet。
5 EL 表达式
EL (Expression Language) 是一种简单的语言,用于从 JSP 页面中获取数据,它简化了 ${requestScope.user.name} 这样的写法。
语法:
作用:
- 获取域对象中的属性值。
${user.name}会依次从 pageScope, requestScope, sessionScope, applicationScope 中查找名为user的对象,然后调用其getName()方法。
- 执行简单的运算。
${1 + 2},${user.age > 18 ? '成年' : '未成年'}
示例:
<%-- 在 Servlet 中设置 --%>
<%
request.setAttribute("user", new User("Zhang San"));
%>
<%-- 在 JSP 中使用 EL 表达式获取 --%>
<h2>用户名: ${user.name}</h2> <%-- 会自动调用 user.getName() --%>
6 JSTL
JSP 标准标签库,用标签代替了 JSP 中的 Java 代码,使页面更加简洁和易于维护。
使用前需要引入标签库:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
常用标签:
c:if: 条件判断<c:if test="${user.age > 18}"> <p>您已成年。</p> </c:if>c:forEach: 循环<c:forEach items="${list}" var="item" varStatus="status"> <p>索引: ${status.index}, 值: ${item}</p> </c:forEach>fmt:formatDate: 格式化日期<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <p>注册日期: <fmt:formatDate value="${user.regDate}" pattern="yyyy-MM-dd"/></p>
第四部分:MVC 设计模式与整合
1 什么是 MVC?
MVC 是一种软件设计模式,旨在将应用程序分为三个相互关联的部分,以实现关注点分离。
-
Model (模型):
- 职责: 负责业务逻辑和数据处理,它不关心如何显示数据。
- 组成: JavaBean (POJO) 和 Service 层。
User.java(数据模型),UserService.java(业务逻辑,如登录验证)。
-
View (视图):
- 职责: 负责数据显示,它只负责展示从 Model 获取的数据,不包含任何业务逻辑。
- 组成: JSP 页面。
login.jsp,welcome.jsp。
-
Controller (控制器):
- 职责: 接收用户请求,调用 Model 处理业务逻辑,然后选择合适的 View 进行响应,它是 Model 和 View 之间的协调者。
- 组成: Servlet。
LoginServlet。
2 为什么使用 MVC?
- 职责清晰: 开发者可以专注于自己的领域(前端、后端、数据库)。
- 可维护性高: 修改业务逻辑不会影响页面展示,修改页面也不会影响后端代码。
- 可重用性好: Model 和 Controller 可以被不同的 View 重用。
- 易于团队协作: 前端和后端可以并行开发。
3 一个完整的 MVC 示例:用户登录
项目结构:
src/main/
java/
com/example/demo/
model/
User.java
service/
UserService.java
controller/
LoginServlet.java
webapp/
WEB-INF/
web.xml
index.jsp (登录页面)
welcome.jsp (欢迎页)
Model (模型)
User.java (简单的 JavaBean)
package com.example.demo.model;
public class User {
private String username;
private String password;
// 构造方法、Getter 和 Setter
public User() {}
public User(String username) {
this.username = username;
}
// ... 省略 getter/setter
}
UserService.java (业务逻辑)
package com.example.demo.service;
import com.example.demo.model.User;
public class UserService {
public boolean login(String username, String password) {
// 这里应该是查询数据库或调用其他服务
// 为了演示,我们写死一个正确的用户名和密码
return "admin".equals(username) && "123456".equals(password);
}
}
View (视图)
index.jsp (登录表单)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>登录</title>
</head>
<body>
<h2>用户登录</h2>
<%-- 如果有错误消息,显示出来 --%>
<c:if test="${not empty errorMessage}">
<p style="color: red;">${errorMessage}</p>
</c:if>
<form action="login" method="post">
用户名: <input type="text" name="username"><br>
密码: <input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
welcome.jsp (登录成功页)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>欢迎页</title>
</head>
<body>
<h2>欢迎, ${sessionScope.user.username}!</h2>
<a href="logout">退出登录</a>
</body>
</html>
Controller (控制器)
LoginServlet.java
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
if (userService.login(username, password)) {
// 1. 登录成功,将用户信息存入 Session
User user = new User(username);
HttpSession session = req.getSession();
session.setAttribute("user", user);
// 2. 请求转发到欢迎页
req.getRequestDispatcher("welcome.jsp").forward(req, resp);
} else {
// 3. 登录失败,将错误信息存入 Request 域,并转发回登录页
req.setAttribute("errorMessage", "用户名或密码错误!");
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
}
}
第五部分:实战项目:简易留言板
这个项目将综合运用前面所学的所有知识点,包括 Servlet, JSP, EL, JSTL, MVC 模式和数据库操作。
需求分析
- 用户可以查看所有留言列表。
- 用户可以发表新留言。
数据库设计
创建一个 message 表:
CREATE DATABASE message_board; USE message_board; CREATE TABLE `message` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `author` VARCHAR(50) NOT NULL, `content` TEXT NOT NULL, `create_time` DATETIME NOT NULL );
项目结构
在 MVC 基础上增加 dao 层。
src/main/
java/
com/example/demo/
dao/
MessageDao.java
model/
Message.java
service/
MessageService.java
controller/
ListServlet.java
PostServlet.java
webapp/
WEB-INF/
index.jsp (留言列表页)
post.jsp (发表留言页)
功能实现
-
留言列表展示
MessageDao.java:findAll()方法查询所有留言。MessageService.java: 调用dao获取数据。ListServlet.java: 调用service获取留言列表,存入request域,并转发到index.jsp。index.jsp: 使用 JSTL 的c:forEach循环显示留言列表。
-
发表新留言
post.jsp: 一个简单的表单,提交到/post。PostServlet.java: 接收表单数据,调用service层保存到数据库,然后重定向回留言列表页 (/list),防止表单重复提交。
这个项目是练习的绝佳机会,建议自己动手实现一遍。
第六部分:进阶与未来
1 过滤器
Filter 是一个可以拦截请求和响应的对象,它可以在请求到达 Servlet 之前,或者在 Servlet 处理完响应之后执行一些操作。
- 用途: 字符编码统一处理、用户权限验证、日志记录等。
- 实现: 实现
javax.servlet.Filter接口,并配置@WebFilter或web.xml。
2 监听器
Listener 用于监听 Web 应用中某些重要事件的发生,并做出相应处理。
- 监听对象: ServletContext, HttpSession, ServletRequest。
- 监听事件: 创建、销毁、属性变化等。
- 用途: 在应用启动时初始化数据、统计在线人数等。
3 从 Servlet/JSP 到现代框架
Servlet 和 JSP 是基础,但直接开发大型项目会变得非常繁琐,现代框架应运而生,它们都基于 Servlet,但提供了更高级的抽象和更强大的功能。
-
Spring MVC
- 简介: Spring 框架的一部分,是 Java Web 领域最成熟、最稳定、使用最广泛的 MVC 框架。
- 优势: 强大的依赖注入、清晰的 MVC 结构、与 Spring 生态(Spring Boot, Spring Data JPA 等)无缝集成。
- 学习路径: 学完 Servlet/JSP 后,学习 Spring MVC 是一个自然的过渡。
-
Spring Boot
- 简介: 并不是一个新框架,而是对 Spring 生态的“封装”和“约定优于配置”思想的极致体现。
- 优势: 极大地简化了项目的配置和部署,通过“起步依赖”(Starter)一键引入所需功能,内置了 Tomcat 服务器,可以快速创建一个可运行的独立应用。
- 现状: Java Web 开发的新一代标准和事实上的王者,对于新手,强烈建议直接从 Spring Boot 开始学习,它能让你更专注于业务逻辑而不是繁琐的配置,理解 Spring Boot 的底层,离不开 Servlet 的知识。
本教程为你提供了一个从零开始的 Servlet & JSP 学习路径,请务必动手实践,从第一个 "Hello, World!" 开始,逐步完成用户登录和留言板项目,扎实的基础是你未来学习更高级技术(如 Spring Boot)的坚实阶梯,祝你学习愉快!
