Java JSP案例基础使用:从零构建动态Web应用的完整指南
📑 目录导读
JSP核心概念与工作原理
动态网页技术演进:在Java Web开发领域,JSP(JavaServer Pages)作为早期成熟的动态页面技术,允许开发者在HTML中嵌入Java代码,实现服务器端数据渲染,与纯Servlet相比,JSP更擅长表现层逻辑,而Servlet更适合控制逻辑。

工作原理图解:
- 用户请求
.jsp文件 → 服务器检查是否首次访问 - 首次访问:JSP引擎将
.jsp翻译为.java(Servlet源码) - 编译为
.class文件 → 实例化成Servlet - 执行
_jspService()方法,生成HTML响应 - 后续访问直接执行已编译的Servlet
关键优势:无需手动编写Servlet代码,分离页面展示与业务逻辑,支持标签库(JSTL)和EL表达式简化开发。
环境配置清单:
- JDK 8+
- Apache Tomcat 9/10
- Eclipse IDE for Enterprise Java (或 IntelliJ IDEA Ultimate)
- Maven 项目构建工具(可选)
JSP页面基础语法详解
脚本元素(Scripting Elements)
声明(Declaration):定义类级变量和方法
<%! int userCount = 0; %>
<%! public String formatDate(Date d) { ... } %>
表达式(Expression):直接输出计算结果
<p>当前用户数:<%= userCount %></p> <p>服务器时间:<%= new java.util.Date() %></p>
脚本段(Scriptlet):嵌入任意Java代码
<%
String userName = request.getParameter("username");
if (userName != null) {
session.setAttribute("user", userName);
}
%>
指令(Directives)
page指令:配置页面属性
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="java.util.*, com.example.model.*" %> <%@ page errorPage="/error.jsp" isErrorPage="false" %>
include指令:静态包含其他文件
<%@ include file="/common/header.jsp" %>
taglib指令:引入标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
动作标签(Action Tags)
<jsp:include page="navigation.jsp" flush="true" />
<jsp:forward page="login.jsp">
<jsp:param name="redirect" value="dashboard" />
</jsp:forward>
<jsp:useBean id="user" class="com.example.User" scope="session" />
<jsp:setProperty name="user" property="name" value="Tom" />
<jsp:getProperty name="user" property="name" />
JSP内置对象实战应用
| 对象名 | 类型 | 作用域 | 典型用途 |
|---|---|---|---|
| request | javax.servlet.http.HttpServletRequest | 请求 | 获取表单数据、HTTP头 |
| response | javax.servlet.http.HttpServletResponse | 响应 | 设置Cookie、重定向 |
| session | javax.servlet.http.HttpSession | 会话 | 用户登录状态跟踪 |
| application | javax.servlet.ServletContext | 应用 | 全局计数器、配置信息 |
| out | javax.servlet.jsp.JspWriter | 页面 | 输出HTML内容 |
| pageContext | javax.servlet.jsp.PageContext | 页面 | 访问其他隐式对象 |
| config | javax.servlet.ServletConfig | 页面 | 获取web.xml初始化参数 |
| page | java.lang.Object | 页面 | 当前Servlet实例引用 |
| exception | java.lang.Throwable | 页面 | 错误页获取异常信息 |
实战案例:用户登录会话管理
<%
// 登录验证逻辑
String username = request.getParameter("username");
String password = request.getParameter("password");
if ("admin".equals(username) && "123456".equals(password)) {
session.setAttribute("loginUser", username);
session.setMaxInactiveInterval(30 * 60); // 30分钟超时
response.sendRedirect("dashboard.jsp");
} else {
request.setAttribute("errorMsg", "用户名或密码错误");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
%>
JSP+Servlet协作案例
MVC模式分离关注点:
- Model:JavaBean + DAO (数据访问对象)
- View:JSP页面
- Controller:Servlet
完整案例:用户列表展示
步骤1:Servlet控制层
@WebServlet("/userList")
public class UserListServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 模拟从数据库获取用户数据
List<User> users = UserDao.getAllUsers();
req.setAttribute("userList", users);
req.getRequestDispatcher("/WEB-INF/userList.jsp").forward(req, resp);
}
}
步骤2:JSP视图层(userList.jsp)
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head><title>用户管理</title></head>
<body>
<h2>用户列表</h2>
<table border="1">
<tr>
<th>ID</th>
<th>用户名</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${userList}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.email}</td>
<td><a href="edit?id=${user.id}">编辑</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
步骤3:web.xml配置(若使用注解可省略)
<servlet>
<servlet-name>UserListServlet</servlet-name>
<servlet-class>com.example.web.UserListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserListServlet</servlet-name>
<url-pattern>/userList</url-pattern>
</servlet-mapping>
数据库连接与JSP交互
JDBC最佳实践(避免直接在JSP写连接代码,应封装在DAO层)
连接池配置(Context.xml示例)
<Context>
<Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/webapp?useSSL=false"
username="root" password="secret"
maxTotal="20" maxIdle="10" maxWaitMillis="10000" />
</Context>
DAO层实现
public class UserDao {
public static List<User> getAllUsers() {
List<User> users = new ArrayList<>();
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mydb");
conn = ds.getConnection();
String sql = "SELECT id, username, email FROM users ORDER BY id";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setEmail(rs.getString("email"));
users.add(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源(使用try-with-resources更佳)
DbUtil.close(rs, stmt, conn);
}
return users;
}
}
常见问题与最佳实践
❓ 问答环节
Q1:JSP页面中<%! %>声明和<% %>脚本段的区别?
- 声明:定义在类级别,可以被多个方法共享,不会出现在_jspService()方法中
- 脚本段:直接嵌入在service方法内部,每次请求都会执行
- 最佳实践:避免使用声明定义方法,推荐将业务逻辑放在Java类中
Q2:为什么我的JSP页面显示乱码?
- 确保JSP文件保存为UTF-8编码
- page指令设置:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> - 如果使用GET请求提交中文,需在
server.xml添加URIEncoding="UTF-8"
Q3:JSP和Freemarker/Thymeleaf相比优劣?
- JSP优势:原生Java支持,丰富的内置对象,成熟的生态(JSTL)
- 现代选择:Thymeleaf更优雅地支持HTML5,Freemarker性能更优
- 建议:新项目考虑Thymeleaf,维护旧系统保持JSP
🚀 优化建议
-
避免Scriptlet:优先使用EL表达式 和JSTL标签
<c:if><c:forEach> -
启用PageFragment:使用
<jsp:include>或自定义标签复用头部/尾部 -
错误处理:配置web.xml统一错误页面
<error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error/generalError.jsp</location> </error-page>
-
安全防护:
- 使用
request.getParameter()时做XSS过滤 - 通过
<c:out value="${param.name}" escapeXml="true" />输出用户输入 - 配置安全约束限制直接访问/WEB-INF目录
- 使用
-
性能调优:
- 启用JSP预编译:通过
jspc工具或容器配置 - 开启Tomcat
development="false"禁用自动刷新 - 静态资源通过CDN或Nginx反向代理
- 启用JSP预编译:通过
本文从JSP基础语法、内置对象、Servlet协作到数据库交互,系统梳理了Java JSP的完整开发流程,掌握这些核心概念后,你可以:
- 快速搭建动态Web页面原型
- 理解传统Java Web项目的架构模式
- 平滑过渡到Spring MVC等现代框架
后续学习路径:JSTL标签库深度使用 → 自定义标签开发 → EL函数扩展 → 结合Spring Boot实现无XML配置