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 页面的开发效率和代码的可读性。

相关推荐
咖啡八杯1 小时前
GoF设计模式——策略模式
java·后端·spring·设计模式
lizhongxuan2 小时前
AI Agent 上下文压缩利器 Headroom
后端
Csvn5 小时前
SSH 远程管理与安全加固 — 运维的守门之道
后端
IT_陈寒5 小时前
Python搞不定字符串编码?这破玩意坑我两小时!
前端·人工智能·后端
菜鸟谢6 小时前
Rust 智能指针完整详解
后端
菜鸟谢6 小时前
Rust 函数完整知识点详解
后端
爱勇宝7 小时前
淡泊名利之前,先承认我们都很焦虑
前端·后端·程序员
菜鸟谢7 小时前
Rust 闭包(Closure)完整详解
后端
ServBay7 小时前
如何利用本地技术栈构建 0 成本 AI SaaS 雏形
后端·aigc·ai编程
菜鸟谢7 小时前
Rust 集合 + 迭代器完整详解
后端