JSP 视图: EL 与 JSTL
JSP 是,它本质上是一个 Servlet(JSP 会被服务器编译为 Servlet 类)。JSP 的核心作用是,实现前后端数据的可视化交互。
一、JSP 实战分析讲解
1. JSP 的概述
JSP 是运行在服务器端的页面技术,它本质上是一个 Servlet(JSP 会被服务器编译为 Servlet 类)。JSP 的核心作用是将后端数据动态渲染到 HTML 页面,实现前后端数据的可视化交互。
JSP 的语法特点:
- 嵌入 Java 代码:用
<% Java代码 %>包裹。 - 输出数据到页面:用
<%= 变量/表达式 %>。 - 声明方法 / 变量:用
<%! 方法/变量声明 %>(不推荐,易引发线程安全问题)。
2. JSP 的生命周期
JSP 的生命周期与 Servlet 一致,分为以下阶段:
- 翻译阶段:服务器将 JSP 文件翻译为 Servlet.java 文件。
- 编译阶段:将 Servlet.java 编译为.class 字节码文件。
- 初始化阶段:创建 Servlet 实例,调用
jspInit()方法(若自定义初始化逻辑)。 - 服务阶段:调用
_jspService()方法处理请求,生成响应页面。 - 销毁阶段:调用
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" /> -
useBean、setProperty、getProperty动作:操作 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:choose、c:when、c: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>
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)