EL隐式对象的实现原理

EL(Expression Language)隐式对象提供了简化在 JSP 页面中访问和操作常用数据的方式。这些隐式对象背后有复杂的机制来实现数据的动态绑定和作用域管理。以下是 EL 隐式对象的工作原理及其实现细节。

EL 隐式对象的实现原理

EL 隐式对象的实现主要依赖于 javax.el 包中的接口和类,如 ELContextELResolverVariableMapper 等。EL 通过这些机制将 JSP 页面中的变量名绑定到实际的对象或数据上。

1. ELContext

ELContext 是 EL 表达式求值时的上下文对象,提供了访问 ELResolverVariableMapper 的方法。在 JSP 运行时,ELContext 包含了当前的上下文信息,如请求、响应、会话等。

2. ELResolver

ELResolver 是一个接口,用于解析 EL 表达式中的变量。EL 通过调用 ELResolvergetValue() 方法来获取表达式的值。多个 ELResolver 可以组成一个链,按顺序解析变量。

java 复制代码
public abstract class ELResolver {
    public abstract Object getValue(ELContext context, Object base, Object property);
}

解释: 当 EL 表达式如 ${param.name} 被求值时,ELResolver 会按顺序查找匹配的变量,并返回其值。

3. VariableMapper

VariableMapper 管理 EL 表达式中的变量和它们的绑定。它提供了 resolveVariable 方法,用于将变量名绑定到实际的表达式或对象。

java 复制代码
public abstract class VariableMapper {
    public abstract ValueExpression resolveVariable(String variable);
}

解释: VariableMapper 允许在 EL 表达式中动态绑定变量,提供了灵活的变量解析机制。

EL 隐式对象的实现

以下是常见的 EL 隐式对象及其实现方式:

1. pageScoperequestScopesessionScopeapplicationScope

这些隐式对象是 Map 实现的,提供对不同作用域变量的访问。它们通过 PageContext 的相应方法实现,如 getAttribute

java 复制代码
// 访问不同作用域的变量
public class ScopeELResolver extends ELResolver {
    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null) {
            String varName = (String) property;
            PageContext pageContext = (PageContext) context.getContext(PageContext.class);

            // 检查页面范围
            Object value = pageContext.getAttribute(varName, PageContext.PAGE_SCOPE);
            if (value == null) {
                // 检查请求范围
                value = pageContext.getAttribute(varName, PageContext.REQUEST_SCOPE);
                if (value == null) {
                    // 检查会话范围
                    value = pageContext.getAttribute(varName, PageContext.SESSION_SCOPE);
                    if (value == null) {
                        // 检查应用范围
                        value = pageContext.getAttribute(varName, PageContext.APPLICATION_SCOPE);
                    }
                }
            }
            return value;
        }
        return null;
    }
}

解释: ScopeELResolver 通过检查 PageContext 的不同作用域来解析变量值。

2. paramparamValues

param 是一个 Map,提供对请求参数的访问,paramValues 提供对请求参数数组的访问。这是通过 HttpServletRequest 实现的。

java 复制代码
// 访问请求参数
public class ParamELResolver extends ELResolver {
    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null) {
            String paramName = (String) property;
            HttpServletRequest request = (HttpServletRequest) context.getContext(HttpServletRequest.class);
            return request.getParameter(paramName);
        }
        return null;
    }
}

解释: ParamELResolver 通过调用 HttpServletRequestgetParameter 方法访问请求参数。

cookie 隐式对象实际是一个Map<String,Cookie>,提供对 Cookie 的访问。每个键是 Cookie 的名称,值是 Cookie 对象。

java 复制代码
// 访问 Cookie
public class CookieELResolver extends ELResolver {
    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null) {
            String cookieName = (String) property;
            HttpServletRequest request = (HttpServletRequest) context.getContext(HttpServletRequest.class);
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookieName.equals(cookie.getName())) {
                        return cookie;
                    }
                }
            }
        }
        return null;
    }
}

解释: CookieELResolver 遍历请求中的 Cookie 数组,匹配名称后返回 Cookie 对象。

EL 表达式的求值过程

  1. 解析表达式 : EL 表达式如 ${userName} 被 JSP 引擎解析。
  2. 查找变量 : EL 引擎使用 ELResolverVariableMapper 查找变量。
  3. 返回值 : 如果找到匹配的变量,返回其值;否则返回 null 或默认值。

示例: 自定义 EL 解析器

你可以自定义 EL 解析器来扩展 EL 的功能。例如,实现一个自定义 ELResolver 来访问自定义数据源。

java 复制代码
public class CustomELResolver extends ELResolver {
    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null) {
            // 自定义解析逻辑
            if ("customData".equals(property)) {
                return "Custom Data Value";
            }
        }
        return null;
    }
}

解释: CustomELResolver 自定义了解析逻辑,允许 EL 表达式访问自定义数据源。

总结

EL 隐式对象的工作原理依赖于 ELContextELResolverVariableMapper 等核心组件,通过这些组件,EL 可以动态地解析和绑定 JSP 页面中的变量和数据。隐式对象提供了对常用数据(如请求参数、会话属性、Cookie 等)的简化访问,从而提高 JSP 页面的开发效率和代码的可读性。

相关推荐
Victor356几秒前
MongoDB(51)什么是分片?
后端
Victor3562 分钟前
MongoDB(50)副本集中的角色有哪些?
后端
daidaidaiyu11 分钟前
Spring IOC 源码学习 声明式事务的入口点
java·spring
myloveasuka25 分钟前
[Java]查找算法&排序算法
java·算法·排序算法
清水白石00832 分钟前
Free-Threaded Python 实战指南:机遇、风险与 PoC 验证方案
java·python·算法
wWYy.37 分钟前
STL:list
开发语言·c++
TON_G-T1 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
发际线还在1 小时前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
飞Link1 小时前
具身智能核心架构之 Python 行为树 (py_trees) 深度剖析与实战
开发语言·人工智能·python·架构
IT_陈寒1 小时前
JavaScript开发者必看:5个让你的代码性能翻倍的隐藏技巧
前端·人工智能·后端