当前位置: 首页 > news >正文

【JavaWeb学习 | 第20篇】EL表达式与JSTL标签 - 实践

个人主页: Hygge_Code
热门专栏:从0开始学习Java | Linux学习| 计算机网络
个人格言: “既然选择了远方,便不顾风雨兼程”

在这里插入图片描述

文章目录

  • EL 表达式与 JSTL 标签详解
    • 一、Servlet回顾
    • 二、EL 表达式(简化数据访问)
      • 1. 什么是 EL 表达式
      • 2. 为什么要用 EL 表达式
      • 3. EL 表达式核心用法‍
        • (1)获取变量值
        • (2)EL 隐式对象
        • (3)获取复杂数据
        • (4)EL 操作符
    • 三、JSTL 标签(解决页面逻辑处理)
      • 1. 什么是 JSTL
      • 2. JSTL 标签库分类
      • 3. JSTL 使用前提
      • 4. 核心标签库常用标签‍
        • (1)通用标签:set、out、remove‍
          • 1. `<c:out>`
          • 2. `<c:set>`
          • 3. `<c:remove>`
        • (2)语法标签:if、choose、forEach‍
          • 1. `<c:if>`
          • 2. `<c:choose>` / `<c:when>` / `<c:otherwise>`
          • 3. 循环标签:`forEach`
        • (3)格式化标签库常用标签‍
          • (1)`fmt:formatDate`:日期格式化
          • (2)`fmt:formatNumber`:数字格式化
    • 四、案例:EL + JSTL 综合应用
      • `index.jsp文件`
      • `ScoreServlet文件`
      • `score.jsp文件`
      • 对比版本:不使用EL表达式和JSTL标签
        • 区别分析
        • 维护成本对比
        • 健壮性与安全性对比
        • 开发效率对比
        • 对比总结

EL 表达式与 JSTL 标签详解

在 JSP 开发中,直接嵌入 Java 小脚本会导致页面结构混乱、维护困难,而 EL 表达式与 JSTL 标签的组合,能完美解决这一问题。它们不仅让页面代码更简洁,还实现了业务逻辑与视图的分离。

一、Servlet回顾

在学习新内容前,先巩固几个关键前置知识点,帮助更好理解后续内容:

  1. Servlet 是接收请求并做出响应的程序,开发方式包括实现 Servlet 接口或继承 HttpServlet,可通过注解或 XML 配置映射路径。
  2. Servlet 生命周期分为实例化、初始化(init)、处理请求(service)、销毁(destroy)四个阶段,随容器启动而创建,随容器关闭而销毁。
  3. 转发通过 RequestDispatcher 的 forward 方法实现,重定向通过 response 的 sendRedirect 方法实现,二者核心区别在于请求域数据是否共享。
  4. 过滤器可拦截请求与响应,多个过滤器组成过滤器链,开发需实现 Filter 接口或继承 HttpFilter,通过 XML 或注解配置生效。

二、EL 表达式(简化数据访问)

1. 什么是 EL 表达式

EL(Expression Language)即表达式语言,是 JSP 内置的简化数据访问的语言,无需编写复杂 Java 代码即可获取域对象中的数据。

2. 为什么要用 EL 表达式

直接使用 Java 小脚本存在诸多弊端:

  • 代码结构混乱,Java 代码与 HTML 标签混合交织;
  • 数据取值需手动实例化对象、强制类型转换,易出错;
  • 代码可读性差,后期维护成本高。
    EL 表达式可替代小脚本,实现数据自动转型,让页面代码更简洁清晰。

3. EL 表达式核心用法‍

(1)获取变量值

语法:${变量名}

  • 无需指定域对象时,EL 会按 pageScope → requestScope → sessionScope → applicationScope 的顺序自动查找;
  • 若多个域对象存在同名变量,优先取作用范围更小的(如 request 优先于 session)。

示例:

// Servlet 中存入数据
request.setAttribute("username", "test");
session.setAttribute("username", "admin");

JSP 页面取值:


当前用户:${username}当前管理员:${sessionScope.username}
(2)EL 隐式对象

通过隐式对象可直接指定取值范围,避免同名变量冲突,常用隐式对象如下:

在这里插入图片描述

(3)获取复杂数据
(4)EL 操作符

EL 支持关系运算、逻辑运算和空值判断,语法简洁直观:
在这里插入图片描述


三、JSTL 标签(解决页面逻辑处理)

1. 什么是 JSTL

JSTL(JavaServer Pages Standard Tag Library)即 JSP 标准标签库,是一套基于 XML 的标签集合,弥补了 EL 无法进行逻辑判断和循环的不足,常与 EL 配合使用。

2. JSTL 标签库分类

JSTL 包含多个功能标签库,开发中最常用核心标签库和格式化标签库:

标签库名称资源标识符(uri)前缀(prefix)核心用途
核心标签库http://java.sun.com/jsp/jstl/corec逻辑判断、循环、变量操作
国际化/格式化标签库http://java.sun.com/jsp/jstl/fmtfmt日期、数字格式化
XML 标签库http://java.sun.com/jsp/jstl/xmlxXML 数据处理(较少用)
数据库标签库http://java.sun.com/jsp/jstl/sqlsql数据库操作(较少用)
函数标签库http://java.sun.com/jsp/jstl/functionsfn字符串处理函数

3. JSTL 使用前提

  1. 引入依赖jar包:jstl.jar 和 standard.jar
  2. JSP 页面顶部声明标签库,示例:

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

4. 核心标签库常用标签‍

(1)通用标签:set、out、remove‍

在这里插入图片描述

1. <c:out>

用于输出数据到页面,类似 <%= %>,但更安全

  • value:要输出的表达式(EL 表达式)
  • default:当 value 为 null 时显示的默认值

2. <c:set>

用于在作用域(page、request、session、application)中设置变量。


  • var:变量名
  • value:变量值(可直接写或用 EL 表达式)
  • scope:作用域(默认 page)
3. <c:remove>

var:要移除的变量的名称
scope:指定要在哪个作用域中移除变量。如果不指定,它会依次在所有作用域(page, request, session, application)中查找该变量并移除(可选属性)

(2)语法标签:if、choose、forEach‍
1. <c:if>

条件判断标签,满足条件时执行标签体内容。

您已成年,可以访问该内容。

  • test:条件表达式(返回 boolean)

2. <c:choose> / <c:when> / <c:otherwise>

多条件判断,类似 Java 的 if-else if-else

优秀

良好

加油


3. 循环标签:forEach

遍历集合或数组,是最常用的 JSTL 标签:


用户名:${user.username}
科目:${score.key},分数:${score.value}
  • items:待遍历的集合/数组;
  • var:每次遍历的元素别名;
  • begin:遍历起始下标(默认 0);
  • end:遍历结束下标;
  • step:遍历步长(默认 1)。
(3)格式化标签库常用标签‍

在这里插入图片描述

(1)fmt:formatDate:日期格式化
<% request.setAttribute("now", new Date()); %>当前日期:当前时间:

运行结果:

在这里插入图片描述

(2)fmt:formatNumber:数字格式化

支持货币、百分比、自定义格式:

<% request.setAttribute("money", 12345.678); %>货币:数字:百分比:

运行结果:

在这里插入图片描述


四、案例:EL + JSTL 综合应用

下面通过一个用户列表展示案例,看如何结合 EL 和 JSTL 开发页面:

index.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>首页显示成绩

ScoreServlet文件

package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@WebServlet("/showScore")
public class ScoreServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("zhangsan",new Score("张三",90));
List<Score> scores = Arrays.asList(new Score("林七夜",90),new Score("江梦南",91),new Score("微微",92),new Score("夏至",93));req.getSession().setAttribute("scores",scores);resp.sendRedirect("score.jsp");}}

score.jsp文件

<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>成绩信息展示
成绩高于80
成绩高于80吗? ${requestScope.result}
成绩优秀
成绩良好
成绩中等
成绩很差
<% request.setAttribute("now", new Date()); %>当前日期:当前时间:
姓名成绩
${score.name}${score.score}
<% request.setAttribute("money", 12345.678); %>货币:数字:百分比:

运行结果(点击链接"显示成绩"后):

在这里插入图片描述

对比版本:不使用EL表达式和JSTL标签

<%@ page import="com.servlet.Score" %>
<%@ page import="java.util.List" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.NumberFormat" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>成绩信息展示 (使用Scriptlet)<%Score zhangsan = (Score) session.getAttribute("zhangsan");boolean result = false;if (zhangsan != null && zhangsan.getScore() > 80) {result = true;out.println("
成绩高于80
");}request.setAttribute("result", result); %>
成绩高于80吗? <%= request.getAttribute("result") %>
<%if (zhangsan != null) {if (zhangsan.getScore() > 90) { %>
成绩优秀
<% } else if (zhangsan.getScore() > 80) { %>
成绩良好
<% } else if (zhangsan.getScore() > 70) { %>
成绩中等
<% } else { %>
成绩很差
<%}} else {// 处理zhangsan为null的情况out.println("
未找到用户信息
");} %> <%@SuppressWarnings("unchecked")List scores = (List) session.getAttribute("scores");if (scores != null && !scores.isEmpty()) {for (Score score : scores) {%><%}}%>
姓名成绩
<%= score.getName() %><%= score.getScore() %>
<%Date now = new Date();request.setAttribute("now", now);SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); %>当前日期:<%= sdfDate.format(now) %>当前时间:<%= sdfDateTime.format(now) %> <%double money = 12345.678;request.setAttribute("money", money);NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();NumberFormat numberFormatter = NumberFormat.getNumberInstance();numberFormatter.setMaximumFractionDigits(2);NumberFormat percentFormatter = NumberFormat.getPercentInstance(); %>货币:<%= currencyFormatter.format(money) %>数字:<%= numberFormatter.format(money) %>百分比:<%= percentFormatter.format(0.75) %>
区别分析
  • EL表达式
    • 简洁${sessionScope.zhangsan.score > 80} 一行代码替代了Scriptlet中获取对象、类型转换、null检查和条件判断的多行代码。
    • 直观:语法接近自然语言,zhangsan.score 直接对应 zhangsan.getScore(),可读性极高。
  • JSTL标签
    • 结构化<c:if>, <c:choose>, <c:forEach> 等标签提供了清晰的逻辑结构,避免了Scriptlet中<% ... %>代码块与HTML标签的混乱交织。
    • 专注视图:标签将Java逻辑封装起来,JSP页面更像一个专注于展示的模板。
维护成本对比
  • 使用 EL + JSTL:
    • 低维护成本
      • 代码逻辑清晰,易于理解和追踪。
      • 如需修改判断条件(如将> 80改为>= 85),只需修改EL表达式中的数字,非常直观。
      • 如需修改循环或格式化规则,只需调整标签的属性。
  • 不使用 EL + JSTL:
    • 高维护成本
      • 代码逻辑分散在多个<% ... %>块中,阅读时需要在Java代码和HTML之间频繁切换上下文。
      • 修改逻辑时,需要在Java代码块中找到对应的iffor语句,容易出错。
      • 代码冗长,增加了阅读和理解的难度。
健壮性与安全性对比
  • 使用 EL + JSTL:
    • 更健壮
      • EL表达式对null有天然的免疫力。如果zhangsannull${zhangsan.score}会返回null,在条件判断中会被当作false,不会抛出NullPointerException
      • JSTL标签(如<c:forEach>)在集合为null时通常会静默处理(不执行循环),增加了页面的稳定性。
  • 不使用 EL + JSTL:
    • 较脆弱
      • 必须手动进行null检查(if (zhangsan != null)),否则程序可能因NullPointerException而崩溃。
      • 类型转换错误(如将一个String强制转为Score)也会导致运行时异常。
开发效率对比
  • 使用 EL + JSTL:
    • 高开发效率
      • 减少了大量重复的模板代码(如getAttribute、类型转换、for循环结构)。
      • 开发者可以更专注于业务逻辑和页面呈现,而非底层的Java语法细节。
  • 不使用 EL + JSTL:
    • 低开发效率
      • 需要编写大量模版代码,增加了编码工作量。
      • 代码量大,也增加了出现语法错误的可能性。
对比总结
对比维度使用 EL表达式 + JSTL标签不使用 (Scriptlet)
代码简洁度,代码量少,逻辑清晰。,代码冗长,充满<% ... %>块。
可读性,语法直观,接近自然语言,结构分明。,Java代码与HTML标签混杂,难以阅读。
维护成本,逻辑集中,修改方便,不易出错。,逻辑分散,修改时需在Java与HTML间切换。
健壮性,自动处理null,减少空指针异常。,需手动处理null和类型转换,易出错。
开发效率,减少重复编码,专注业务。,编写大量样板代码,效率低下。

如果我的内容对你有帮助,请 点赞 评论 收藏 。创作不易,大家的支持就是我坚持下去的动力!
在这里插入图片描述

http://www.jsqmd.com/news/334388/

相关文章:

  • 数据一致性与容灾——RTO/RPO指标、备份演练与依赖链风险识别
  • day74(2.2)——leetcode面试经典150
  • 从认知到转化:DeepSeek推广公司的全链路营销解决方案 - 品牌2026
  • 2026年智能电动天窗供应商TOP10榜单,谁将引领行业新标准 - 品牌企业推荐师(官方)
  • <span class=“js_title_inner“>LeCunamp;谢赛宁团队重磅论文:RAE能大规模文生图了,比VAE更好!</span>
  • 为什么领先品牌选择DeepSeek推广公司进行AI营销部署 - 品牌2026
  • 与DeepSeek推广公司合作,构建您的智能营销竞争力 - 品牌2026
  • 教你零成本使用满血 Clawdbot,并手把手带你集成飞书和Telegram
  • 智能营销实战:DeepSeek推广公司成功案例深度解析 - 品牌2026
  • 基于深度学习的狗品种检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
  • P1060 [NOIP 2006 普及组] 开心的金明
  • Java打造旅行攻略及搭子匹配系统源码
  • 2026最强Java面试八股文及答案整理
  • 不用 Xcode 上架 iOS,拆分流程多工具协作完成 iOS 应用的发布准备与提交流程
  • 如果您的品牌需要AI营销赋能,从了解DeepSeek推广公司开始 - 品牌2026
  • 【快速EI检索 | ICPS出版 | 高校背书;检索稳定、连续4年实现EI(核心)、Scopus双检索,快至刊后1个月检索】第五届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2026)
  • Agentic AI提示工程情境感知增强技术,为何成为提示工程架构师的新宠?
  • 什么是网络安全?网络安全防范技术包括哪些?
  • 提升仓储管理效率,其实没您想的那么难
  • 【面板数据】地市工业三废数据集(2003-2023年)
  • 从策略到执行:DeepSeek推广公司如何助力企业实现营销升级 - 品牌2026
  • 赋能数据决策!10款好用的BI工具核心能力速览,适配多行业场景
  • 【机器人路径规划】移动机器人导航中RRT、RRT_和RRT_-Smart路径规划算法的比较附matlab代码
  • Web 安全基础教程:从零基础入门到精通
  • 【快速EI检索 | IEEE出版 | 高效出版流程 | 审稿周期短 | 快速录用 | 征稿主题范围广】第二届信号处理、通信与控制系统国际学术会议(SPCCS 2026)
  • 从“字节”到“自注意力”:把大模型参数这件事讲透
  • 改变工作方式的 PostgreSQL 实用模式
  • 揭秘网络安全:从零基础到高手的必由之路
  • Java助力:旅游手册搭子系统源码全解析
  • <span class=“js_title_inner“>第149篇:基于机器学习的字符N-Gram与 XGBoost模型的DGA恶意域名高效识别方法讲解</span>