JSP 表达式语言(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在 Java Web 开发中,JSP(JavaServer Pages)作为动态网页技术的核心工具,其表达式语言(Expression Language,简称 EL)扮演着重要角色。它简化了开发流程,让开发者能够更高效地访问数据、操作变量,并与后端 Java 对象无缝衔接。对于编程初学者和中级开发者而言,掌握 JSP 表达式语言不仅能提升编码效率,还能为理解更复杂的 Web 开发框架打下坚实基础。本文将从基础语法、核心功能到实际案例,逐步解析这一技术,帮助读者轻松上手并灵活应用。


一、JSP 表达式语言的诞生背景与核心作用

1.1 JSP 表达式语言的诞生背景

早期的 JSP 开发中,开发者需要通过 <%= %> 语法直接嵌入 Java 代码来输出数据,例如:

当前时间: <%= new java.util.Date() %>  

这种写法虽然直接,但存在两个问题:

  1. 代码可读性低:混合 HTML 和 Java 代码会导致页面结构混乱;
  2. 扩展性受限:当需要频繁操作复杂数据(如集合、对象属性)时,代码量会显著增加。

为解决这些问题,JSP 表达式语言应运而生。它通过简洁的语法,让开发者无需编写 Java 代码即可访问数据,同时保持页面的清晰与可维护性。

1.2 核心作用与优势

JSP 表达式语言的核心作用可概括为以下三点:

  1. 数据访问:通过类似路径的语法(如 ${user.name})直接读取 Java 对象的属性;
  2. 运算简化:支持基础运算符(如 +-==),减少对脚本的依赖;
  3. 隐式对象集成:无缝对接 JSP 内置对象(如 requestsession),简化数据交互。

形象比喻
可以将 EL 视为一位“翻译官”,它将复杂的 Java 对象路径翻译成更易读的语法形式,同时隐藏了底层的复杂实现细节。


二、JSP 表达式语言的基础语法

2.1 基本表达式结构

JSP 表达式语言的表达式以 ${ 开头,} 结尾,例如:

当前用户:${user.name}  

此表达式的作用是:

  1. 从 JSP 的隐式对象(如 pageScoperequest)中查找名为 user 的对象;
  2. 调用该对象的 getName() 方法(或直接访问 name 字段)获取值;
  3. 将结果以字符串形式输出到页面中。

2.2 变量与运算符

2.2.1 变量访问

EL 表达式支持以下变量类型:
| 变量类型 | 作用域 | 示例 |
|-------------------|----------------------|--------------------------|
| pageScope | 当前页面 | ${pageScope.user} |
| requestScope | 请求范围 | ${requestScope.user} |
| sessionScope | 会话范围 | ${sessionScope.user} |
| applicationScope | 应用程序范围 | ${applicationScope.user} |

示例
user 对象存储在 request 范围中,则 ${user} 默认等同于 ${requestScope.user}

2.2.2 运算符

EL 支持以下运算符,可直接在表达式中使用:

  • 算术运算符+(加)、-(减)、*(乘)、/(除)、%(取模)
  • 比较运算符==!=<><=>=
  • 逻辑运算符&&(与)、||(或)、!(非)
  • 空值运算符??(判断变量是否存在)

示例

总金额:${price * quantity}  
是否登录:${user.loggedIn ?? '未找到用户' : user.loggedIn ? '已登录' : '未登录'}  

三、隐式对象与数据访问

3.1 隐式对象概述

JSP 表达式语言默认提供了 11 个隐式对象(Implicit Objects),无需显式声明即可直接使用。这些对象覆盖了请求处理、会话管理、页面上下文等核心场景。

关键隐式对象示例
| 对象名称 | 功能描述 | 典型用法 |
|----------------|---------------------------------------|-----------------------------------|
| pageContext | 管理当前页面的上下文信息 | ${pageContext.request.contextPath} |
| request | 获取请求参数、属性等信息 | ${request.getParameter('username')} |
| session | 访问会话范围内的对象 | ${session.getAttribute('cart')} |
| application | 访问全局应用程序范围的对象 | ${application.getAttribute('siteConfig')} |

3.2 数据访问的“路径导航”特性

EL 表达式支持通过“路径”方式逐层访问对象属性,例如:

<!-- 假设 user 对象包含 address 属性,address 包含 city 属性 -->  
用户所在城市:${user.address.city}  

若路径中的任何一层对象为 null,表达式会自动返回空字符串而非抛出异常,这一特性被称为 “空值安全”


四、JSP 表达式语言的进阶用法

4.1 自定义对象与 EL 集成

当需要访问自定义 Java 对象的属性时,需确保该对象遵循以下规则:

  1. 提供标准的 gettersetter 方法(如 getName()setName());
  2. 或直接暴露 public 访问权限的字段(非推荐,但可直接通过字段名访问)。

示例

public class Product {  
    private String name;  
    private Double price;  
    // 必须提供 getter 方法  
    public String getName() { return name; }  
}  

在 JSP 中即可直接调用:

商品名称:${product.name}  

4.2 集合与数组操作

EL 表达式支持对 MapList、数组等集合类型进行操作:

  • 访问 Map 的值${map['key']}${map.key}(若键为合法标识符);
  • 访问 List/数组的元素${list[0]}
  • 遍历集合:结合 JSTL 的 <c:forEach> 标签。

示例

<!-- 遍历用户列表 -->  
<c:forEach items="${users}" var="user">  
    用户名:${user.name}<br>  
</c:forEach>  

五、实战案例:构建一个简单的购物车系统

5.1 需求分析

实现一个简单的购物车页面,需展示以下信息:

  1. 当前用户信息(从 session 中获取);
  2. 购物车中的商品列表;
  3. 商品总价计算。

5.2 代码实现

5.2.1 后端数据准备(Servlet)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    // 模拟用户登录  
    User user = new User("张三", "user123");  
    session.setAttribute("user", user);  

    // 模拟购物车数据  
    List<Product> cart = new ArrayList<>();  
    cart.add(new Product("笔记本电脑", 5999.0));  
    cart.add(new Product("无线耳机", 499.0));  
    request.setAttribute("cart", cart);  

    request.getRequestDispatcher("/WEB-INF/views/cart.jsp").forward(request, response);  
}  

5.2.2 前端页面(cart.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>  
<html>  
<head>  
    <title>购物车</title>  
</head>  
<body>  
    <h1>欢迎,${user.name}!</h1>  
    <h2>购物车列表</h2>  
    <table border="1">  
        <tr>  
            <th>商品名称</th>  
            <th>单价(元)</th>  
        </tr>  
        <c:forEach items="${cart}" var="product">  
            <tr>  
                <td>${product.name}</td>  
                <td>${product.price}</td>  
            </tr>  
        </c:forEach>  
    </table>  

    <!-- 计算总价 -->  
    <c:set var="total" value="0" scope="request"/>  
    <c:forEach items="${cart}" var="product">  
        <c:set var="total" value="${total + product.price}"/>  
    </c:forEach>  
    <h3>总价:${total} 元</h3>  
</body>  
</html>  

5.3 关键点解析

  1. 用户信息展示:通过 ${user.name} 直接访问 session 中存储的用户对象属性;
  2. 商品列表遍历:利用 JSTL 的 <c:forEach> 标签结合 EL 表达式,实现数据动态渲染;
  3. 总价计算:通过 <c:set> 标签和 EL 的加法运算,逐步累加商品价格,最终输出结果。

六、最佳实践与注意事项

6.1 推荐实践

  1. 优先使用 EL 而非脚本:例如用 ${user.loggedIn} 替代 <%= user.loggedIn %>
  2. 结合 JSTL 标签库:JSTL(JSP Standard Tag Library)提供了 corefmt 等标签,与 EL 配合可实现更复杂逻辑;
  3. 利用空值安全特性:避免因对象为空导致的 NullPointerException

6.2 常见误区

  • 误用 . 运算符:若属性名包含特殊字符(如 user-name),需改用 ['user-name'] 的形式访问;
  • 忽略作用域范围:若多个作用域中存在同名变量,需显式指定(如 ${sessionScope.user})。

结论

JSP 表达式语言作为简化 Web 开发的重要工具,其简洁语法和强大的数据访问能力,为开发者提供了高效编码的可能。无论是基础的变量操作,还是复杂的数据遍历与计算,EL 均能通过直观的语法实现,同时避免了直接嵌入脚本带来的代码混乱问题。

对于初学者而言,建议从简单的变量访问开始,逐步掌握隐式对象和集合操作,最终通过实际项目(如购物车、用户管理)巩固技能。对于中级开发者,则可深入研究 EL 与 JSTL、自定义标签的结合,进一步提升开发效率。

掌握 JSP 表达式语言不仅是技术能力的提升,更是理解 Web 前后端数据交互逻辑的关键一步。希望本文能帮助读者系统性地理解这一技术,并在实际开发中灵活运用。

最新发布