JSP基础
- [JSP(Java Server Pages)基础详解](#JSP(Java Server Pages)基础详解)
-
- [一、JSP 概述](#一、JSP 概述)
-
- [1.1 什么是 JSP?](#1.1 什么是 JSP?)
- [1.2 JSP 工作原理](#1.2 JSP 工作原理)
- [二、JSP 基本语法](#二、JSP 基本语法)
-
- [2.1 JSP 脚本元素](#2.1 JSP 脚本元素)
- [2.2 示例:完整的 JSP 页面](#2.2 示例:完整的 JSP 页面)
- [三、JSP 指令](#三、JSP 指令)
-
- [3.1 指令类型对比表](#3.1 指令类型对比表)
- [3.2 page 指令详细属性](#3.2 page 指令详细属性)
- [四、JSP 隐含对象](#四、JSP 隐含对象)
-
- [4.1 九大隐含对象](#4.1 九大隐含对象)
- [4.2 隐含对象示例](#4.2 隐含对象示例)
- [五、JSP 作用域](#五、JSP 作用域)
-
- [5.1 四种作用域对比](#5.1 四种作用域对比)
- [5.2 作用域使用示例](#5.2 作用域使用示例)
- [六、JSP 动作标签](#六、JSP 动作标签)
-
- [6.1 常用动作标签](#6.1 常用动作标签)
- [6.2 动作标签示例](#6.2 动作标签示例)
- [七、JSP 与 Servlet 交互](#七、JSP 与 Servlet 交互)
-
- [7.1 JSP 生命周期方法](#7.1 JSP 生命周期方法)
- [7.2 MVC 模式中的 JSP](#7.2 MVC 模式中的 JSP)
- [八、JSP 最佳实践](#八、JSP 最佳实践)
-
- [8.1 编码规范](#8.1 编码规范)
- [8.2 示例:商品列表页面](#8.2 示例:商品列表页面)
- 九、常见问题解决
-
- [9.1 中文乱码问题](#9.1 中文乱码问题)
- [9.2 路径问题](#9.2 路径问题)
JSP(Java Server Pages)基础详解
一、JSP 概述
1.1 什么是 JSP?
JSP 是一种动态网页技术,允许在 HTML 中嵌入 Java 代码。它运行在服务器端,生成动态内容后发送给客户端浏览器。
1.2 JSP 工作原理
复制代码
JSP文件 → (编译) → Servlet类 → (执行) → HTML响应
二、JSP 基本语法
2.1 JSP 脚本元素
| 语法类型 |
格式 |
描述 |
示例 |
| 脚本片段 |
<% ... %> |
插入 Java 代码 |
<% int x = 10; %> |
| 表达式 |
<%= ... %> |
输出表达式结果 |
<%= new java.util.Date() %> |
| 声明 |
<%! ... %> |
声明变量或方法 |
<%! int count = 0; %> |
| 指令 |
<%@ ... %> |
JSP 页面指令 |
<%@ page import="java.util.*" %> |
| 注释 |
<%-- ... --%> |
JSP 注释,不发送到客户端 |
<%-- 这是注释 --%> |
2.2 示例:完整的 JSP 页面
jsp
复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.Date, java.text.SimpleDateFormat" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 示例</title>
</head>
<body>
<%-- 声明部分 --%>
<%!
private int visitorCount = 0;
public String getWelcomeMessage() {
return "欢迎访问我们的网站!";
}
%>
<%-- 脚本片段 --%>
<%
visitorCount++;
String name = request.getParameter("name");
if (name == null) name = "访客";
%>
<h1><%= getWelcomeMessage() %></h1>
<%-- 表达式 --%>
<p>您好,<%= name %>!您是第 <%= visitorCount %> 位访客。</p>
<p>当前时间:<%= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) %></p>
</body>
</html>
三、JSP 指令
3.1 指令类型对比表
| 指令 |
语法 |
主要属性 |
功能描述 |
| page |
<%@ page ... %> |
language, contentType, import, session, buffer, errorPage, isErrorPage |
定义页面属性 |
| include |
<%@ include ... %> |
file |
静态包含文件 |
| taglib |
<%@ taglib ... %> |
uri, prefix |
引入标签库 |
3.2 page 指令详细属性
jsp
复制代码
<%@ page
language="java" <%-- 脚本语言,只能是 java --%>
contentType="text/html; charset=UTF-8" <%-- MIME 类型和字符编码 --%>
pageEncoding="UTF-8" <%-- JSP 文件本身的编码 --%>
import="java.util.*, java.sql.*" <%-- 导入包,可多个用逗号分隔 --%>
session="true" <%-- 是否启用 session,默认 true --%>
buffer="8kb" <%-- 缓冲区大小 --%>
autoFlush="true" <%-- 自动刷新缓冲区 --%>
isThreadSafe="true" <%-- 是否线程安全 --%>
errorPage="error.jsp" <%-- 错误处理页面 --%>
isErrorPage="false" <%-- 是否是错误页面 --%>
extends="package.class" <%-- 继承的父类 --%>
%>
四、JSP 隐含对象
4.1 九大隐含对象
| 对象名 |
类型 |
作用域 |
描述 |
| request |
HttpServletRequest |
request |
客户端请求信息 |
| response |
HttpServletResponse |
page |
服务器响应 |
| session |
HttpSession |
session |
用户会话 |
| application |
ServletContext |
application |
应用上下文 |
| out |
JspWriter |
page |
输出流 |
| config |
ServletConfig |
page |
Servlet 配置 |
| pageContext |
PageContext |
page |
页面上下文 |
| page |
Object |
page |
当前页实例 |
| exception |
Throwable |
page |
异常对象(仅错误页可用) |
4.2 隐含对象示例
jsp
复制代码
<%
// 1. 使用 request 获取参数
String username = request.getParameter("username");
// 2. 使用 session 存储数据
session.setAttribute("user", username);
// 3. 使用 application 存储全局数据
Integer totalVisits = (Integer) application.getAttribute("totalVisits");
if (totalVisits == null) totalVisits = 0;
application.setAttribute("totalVisits", totalVisits + 1);
// 4. 使用 response 重定向
if (username == null) {
response.sendRedirect("login.jsp");
}
// 5. 使用 out 输出
out.println("欢迎您," + username);
%>
五、JSP 作用域
5.1 四种作用域对比
| 作用域 |
对象 |
生命周期 |
适用场景 |
| page |
pageContext |
当前页面 |
页面内数据传递 |
| request |
request |
一次请求 |
请求转发时的数据传递 |
| session |
session |
用户会话 |
用户登录信息、购物车 |
| application |
application |
应用运行期 |
全局配置、计数器 |
5.2 作用域使用示例
jsp
复制代码
<%
// 设置不同作用域的属性
pageContext.setAttribute("pageVar", "页面变量"); // page 作用域
request.setAttribute("requestVar", "请求变量"); // request 作用域
session.setAttribute("sessionVar", "会话变量"); // session 作用域
application.setAttribute("appVar", "应用变量"); // application 作用域
// 获取属性(按作用域搜索顺序:page → request → session → application)
String value = (String) pageContext.findAttribute("sessionVar");
%>
<!-- 使用 EL 表达式获取作用域变量 -->
<p>页面变量:${pageScope.pageVar}</p>
<p>请求变量:${requestScope.requestVar}</p>
<p>会话变量:${sessionScope.sessionVar}</p>
<p>应用变量:${applicationScope.appVar}</p>
六、JSP 动作标签
6.1 常用动作标签
| 标签 |
语法 |
描述 |
| jsp:include |
<jsp:include page="url" /> |
动态包含文件 |
| jsp:forward |
<jsp:forward page="url" /> |
请求转发 |
| jsp:param |
<jsp:param name="param" value="value" /> |
传递参数 |
| jsp:useBean |
<jsp:useBean id="bean" class="package.class" /> |
使用 JavaBean |
| jsp:setProperty |
<jsp:setProperty name="bean" property="*" /> |
设置 Bean 属性 |
| jsp:getProperty |
<jsp:getProperty name="bean" property="name" /> |
获取 Bean 属性 |
6.2 动作标签示例
jsp
复制代码
<%-- 1. 动态包含 --%>
<jsp:include page="header.jsp">
<jsp:param name="title" value="首页" />
</jsp:include>
<%-- 2. 使用 JavaBean --%>
<jsp:useBean id="user" class="com.example.User" scope="session">
<jsp:setProperty name="user" property="*" />
</jsp:useBean>
<%-- 3. 显示 Bean 属性 --%>
<p>用户名:<jsp:getProperty name="user" property="name" /></p>
<p>邮箱:<jsp:getProperty name="user" property="email" /></p>
<%-- 4. 请求转发 --%>
<%
if (user == null) {
%>
<jsp:forward page="login.jsp" />
<%
}
%>
七、JSP 与 Servlet 交互
7.1 JSP 生命周期方法
jsp
复制代码
<%!
// JSP 初始化方法
public void jspInit() {
System.out.println("JSP 初始化");
}
// JSP 销毁方法
public void jspDestroy() {
System.out.println("JSP 销毁");
}
%>
<%
// _jspService() 方法的内容写在脚本片段中
if (request.getMethod().equals("POST")) {
// 处理 POST 请求
}
%>
7.2 MVC 模式中的 JSP
复制代码
客户端 → Servlet(Controller) → 处理请求
↓
调用业务逻辑(Model)
↓
转发到 JSP(View)
↓
客户端 ← 返回 HTML 响应 ←
Servlet 示例:
java
复制代码
@WebServlet("/user")
public class UserServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 获取数据(Model)
UserService service = new UserService();
List<User> users = service.getAllUsers();
// 2. 设置请求属性
request.setAttribute("userList", users);
// 3. 转发到 JSP(View)
request.getRequestDispatcher("/users.jsp").forward(request, response);
}
}
对应 JSP:
jsp
复制代码
<%@ page import="java.util.List, com.example.User" %>
<table border="1">
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
</tr>
<%
List<User> users = (List<User>) request.getAttribute("userList");
for (User user : users) {
%>
<tr>
<td><%= user.getId() %></td>
<td><%= user.getName() %></td>
<td><%= user.getEmail() %></td>
</tr>
<% } %>
</table>
八、JSP 最佳实践
8.1 编码规范
- 避免在 JSP 中写过多 Java 代码:使用 EL 表达式和 JSTL
- 合理使用作用域:根据数据生命周期选择合适的作用域
- 统一字符编码:始终设置 UTF-8 编码
- 异常处理:使用 errorPage 机制
8.2 示例:商品列表页面
jsp
复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>商品列表</title>
<style>
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
tr:nth-child(even) { background-color: #f9f9f9; }
</style>
</head>
<body>
<h1>商品列表</h1>
<%-- 使用 JSTL 替代脚本代码 --%>
<c:if test="${not empty message}">
<p style="color: green;">${message}</p>
</c:if>
<table>
<tr>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>库存</th>
<th>操作</th>
</tr>
<%-- JSTL 循环 --%>
<c:forEach var="product" items="${productList}">
<tr>
<td>${product.id}</td>
<td>${product.name}</td>
<td>¥${product.price}</td>
<td>${product.stock}</td>
<td>
<a href="productDetail?id=${product.id}">查看</a>
<a href="addToCart?id=${product.id}">加入购物车</a>
</td>
</tr>
</c:forEach>
</table>
<%-- 分页 --%>
<div>
<c:if test="${page > 1}">
<a href="productList?page=${page - 1}">上一页</a>
</c:if>
第 ${page} 页 / 共 ${totalPages} 页
<c:if test="${page < totalPages}">
<a href="productList?page=${page + 1}">下一页</a>
</c:if>
</div>
</body>
</html>
九、常见问题解决
9.1 中文乱码问题
jsp
复制代码
<%-- 方案1:在 JSP 头部设置 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
<%-- 方案2:在 Servlet 中设置 --%>
<%
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
%>
9.2 路径问题
jsp
复制代码
<%-- 使用绝对路径 --%>
<a href="${pageContext.request.contextPath}/product/list.jsp">产品列表</a>
<%-- 使用 base 标签 --%>
<head>
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
</head>
通过以上基础内容的学习,您应该能够掌握 JSP 的核心概念和基本用法。在实际开发中,建议结合 EL 表达式、JSTL 标签库和 MVC 模式来构建更清晰、更易维护的 Web 应用。