一、JSP 实战分析讲解

1. JSP 的概述

JSP 是运行在服务器端的页面技术,它本质上是一个 Servlet(JSP 会被服务器编译为 Servlet 类)。JSP 的核心作用是将后端数据动态渲染到 HTML 页面,实现前后端数据的可视化交互。

JSP 的语法特点:

  • 嵌入 Java 代码:用<% Java代码 %>包裹。
  • 输出数据到页面:用<%= 变量/表达式 %>
  • 声明方法 / 变量:用<%! 方法/变量声明 %>(不推荐,易引发线程安全问题)。

2. JSP 的生命周期

JSP 的生命周期与 Servlet 一致,分为以下阶段:

  1. 翻译阶段:服务器将 JSP 文件翻译为 Servlet.java 文件。
  2. 编译阶段:将 Servlet.java 编译为.class 字节码文件。
  3. 初始化阶段:创建 Servlet 实例,调用jspInit()方法(若自定义初始化逻辑)。
  4. 服务阶段:调用_jspService()方法处理请求,生成响应页面。
  5. 销毁阶段:调用jspDestroy()方法(若自定义销毁逻辑)。

3. JSP 的四大域对象

JSP 中内置了四个 “域对象”,用于在不同范围共享数据:

域对象 作用范围 对应的 Servlet 对象
pageContext 当前 JSP 页面(仅当前页面有效) 无(JSP 独有)
request 一次请求响应(转发内有效) HttpServletRequest
session 一次会话(用户登录后直到会话结束) HttpSession
application 整个 Web 应用(服务器启动到关闭) ServletContext

示例:在 JSP 中存储和获取数据

<%
    pageContext.setAttribute("pageMsg", "页面级数据");
    request.setAttribute("reqMsg", "请求级数据");
    session.setAttribute("sessionMsg", "会话级数据");
    application.setAttribute("appMsg", "应用级数据");
%>

<!-- 获取数据 -->
页面级数据:${pageScope.pageMsg}<br>
请求级数据:${requestScope.reqMsg}<br>
会话级数据:${sessionScope.sessionMsg}<br>
应用级数据:${applicationScope.appMsg}<br>

4. JSP 的指令标签

JSP 指令用于设置页面的全局属性,格式为<%@ 指令名 属性="值" %>,常见指令:

  • page指令:设置页面的编码、语言、会话支持等。示例:

    <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ page session="true" %> <!-- 启用会话支持,默认true -->
    
  • include指令:静态包含其他页面(编译时合并为一个 Servlet)。示例:

    <%@ include file="header.jsp" %> <!-- 包含头部公共页面 -->
    <h1>正文内容</h1>
    <%@ include file="footer.jsp" %> <!-- 包含底部公共页面 -->
    
  • taglib指令:引入标签库(如 JSTL 标签库)。示例:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    

5. JSP 的动作标签

JSP 动作标签是运行时的行为控制,格式为<jsp:动作名 属性="值" />,常见动作:

  • forward动作:请求转发(与request.getRequestDispatcher().forward()效果一致)。示例

    <jsp:forward page="/home.jsp" />
    
  • include动作:动态包含其他页面(运行时分别处理,再合并响应)。示例:

    <jsp:include page="header.jsp" />
    
  • useBeansetPropertygetProperty动作:操作 JavaBean 对象。示例:

    <jsp:useBean id="user" class="com.example.User" scope="request" />
    <jsp:setProperty name="user" property="name" value="张三" />
    <jsp:setProperty name="user" property="age" value="25" />
    用户名:<jsp:getProperty name="user" property="name" /><br>
    年龄:<jsp:getProperty name="user" property="age" />
    

二、EL 表达式和 JSTL 标签库的使用

1. EL 表达式(Expression Language)

EL 表达式是简化 JSP 中 Java 代码的表达式语言,它可以快速获取域对象中的数据、执行简单运算和逻辑判断。

(1)EL 的语法

EL 表达式以${}包裹,示例:

${user.name} <!-- 获取域对象中user的name属性 -->
${10 + 20} <!-- 运算,结果为30 -->
${empty list} <!-- 判断list是否为空 -->

(2)EL 获取数据的优先级

EL 获取数据时,会按以下顺序查找域对象:pageContext → request → session → application(找到即返回,否则返回null)。

示例:

<%
    request.setAttribute("msg", "请求域数据");
    session.setAttribute("msg", "会话域数据");
%>
${msg} <!-- 输出“请求域数据”,因为request优先级高于session -->

(3)EL 的隐含对象

EL 提供了多个隐含对象,用于简化操作:

隐含对象 作用
pageScope 仅在 pageContext 域中查找数据
requestScope 仅在 request 域中查找数据
sessionScope 仅在 session 域中查找数据
applicationScope 仅在 application 域中查找数据
param 获取请求参数(单个值)
paramValues 获取请求参数(多个值,返回数组)
header 获取请求头
cookie 获取 Cookie

示例:

<!-- 获取请求参数username -->
${param.username}<br>
<!-- 获取Cookie中的JSESSIONID -->
${cookie.JSESSIONID.value}<br>

2. JSTL 标签库(JSP Standard Tag Library)

JSTL 是JSP 的标准标签库,它提供了一系列标签,用于替代 JSP 中的 Java 代码,实现循环、判断、格式化等功能。使用前需先引入 JSTL 的 jar 包,并通过taglib指令引入标签库。

(1)核心标签库(c标签)

核心标签库是 JSTL 最常用的部分,用于流程控制、集合操作等。

  • c:if标签:条件判断。示例:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <c:if test="${user.age >= 18}">
        <p>您已成年</p>
    </c:if>
    <c:if test="${user.age < 18}">
        <p>您未成年</p>
    </c:if>
    
  • c:choosec:whenc:otherwise标签:多条件判断。示例:

    <c:choose>
        <c:when test="${user.score >= 90}">
            <p>优秀</p>
        </c:when>
        <c:when test="${user.score >= 80}">
            <p>良好</p>
        </c:when>
        <c:otherwise>
            <p>加油</p>
        </c:otherwise>
    </c:choose>
    
  • c:forEach标签:循环遍历集合。示例:遍历用户列表

    <c:forEach items="${userList}" var="user" varStatus="status">
        <tr>
            <td>${status.index + 1}</td> <!-- 索引(从0开始)+1 -->
            <td>${user.name}</td>
            <td>${user.age}</td>
        </tr>
    </c:forEach>
    
  • c:set标签:设置域对象中的属性。示例:

    <c:set var="msg" value="Hello JSTL" scope="request" />
    ${requestScope.msg} <!-- 输出Hello JSTL -->
    

(2)格式化标签库(fmt标签)

格式化标签库用于格式化日期、数字等数据。

示例:格式化日期

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss" />

示例:格式化数字

<fmt:formatNumber value="${price}" pattern="0.00" /> <!-- 格式化为两位小数,如123.45 -->

三、JSP、EL、JSTL 综合实战:用户列表展示

需求:从后端获取用户列表,在 JSP 中用 EL 和 JSTL 展示,包含条件判断和循环遍历。

(1)后端 Servlet 准备数据

@WebServlet("/userList")
public class UserListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<User> userList = new ArrayList<>();
        userList.add(new User(1, "张三", 25, "男"));
        userList.add(new User(2, "李四", 30, "女"));
        userList.add(new User(3, "王五", 22, "男"));
        
        req.setAttribute("userList", userList);
        req.getRequestDispatcher("/userList.jsp").forward(req, resp);
    }
}

class User {
    private int id;
    private String name;
    private int age;
    private String gender;
    // 构造器、getter/setter省略
}

(2)JSP 页面展示数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>用户列表</title>
    <style>
        table { border-collapse: collapse; }
        td, th { border: 1px solid #ccc; padding: 8px; }
    </style>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        <tr>
            <th>序号</th>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>状态</th>
        </tr>
        <c:forEach items="${userList}" var="user" varStatus="status">
            <tr>
                <td>${status.count}</td> <!-- 计数(从1开始) -->
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>${user.age}</td>
                <td>${user.gender}</td>
                <td>
                    <c:if test="${user.age >= 18}">成年</c:if>
                    <c:if test="${user.age < 18}">未成年</c:if>
                </td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐