JavaWeb开发系列(六)JSP基础

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 编码规范

  1. 避免在 JSP 中写过多 Java 代码:使用 EL 表达式和 JSTL
  2. 合理使用作用域:根据数据生命周期选择合适的作用域
  3. 统一字符编码:始终设置 UTF-8 编码
  4. 异常处理:使用 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 应用。

相关推荐
兆子龙8 小时前
ahooks useRequest 深度解析:一个 Hook 搞定所有请求
java·javascript
兆子龙8 小时前
React Suspense 从入门到实战:让异步加载更优雅
java·javascript
咕白m62511 小时前
Java 实现 Excel 转 HTML:完整示例
java
RealPluto11 小时前
Spring AOP 失效排查
java·spring
码路飞12 小时前
热榜全是 OpenClaw,但我用 50 行 Python 就造了个桌面 AI Agent 🤖
java·javascript
Nyarlathotep011312 小时前
LinkedList源码分析
java·后端
用户83071968408212 小时前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
带刺的坐椅13 小时前
SolonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)
java·ai·agent·solon·solon-ai·claude-code·openclaw
会员源码网14 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java