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

相关推荐
Tao____几秒前
国产开源物联网平台
java·物联网·mqtt·iot·设备对接
uup几秒前
RabbitMQ 在 Java 应用中消费者无法连接问题
java·rabbitmq
繁华似锦respect3 分钟前
C++ 设计模式之观察者模式详细介绍
linux·开发语言·c++·windows·观察者模式·设计模式·visual studio
做cv的小昊5 分钟前
在NanoPC-T6开发板上通过USB串口通信实现光源控制功能
java·后端·嵌入式硬件·边缘计算·安卓·信息与通信·开发
用户69371750013846 分钟前
21.Kotlin 接口:接口 (Interface):抽象方法、属性与默认实现
android·后端·kotlin
溪饱鱼6 分钟前
主动与被动AI交互范式
前端·后端·aigc
写代码的皮筏艇8 分钟前
Sequelize 详细指南
前端·后端
敲代码的嘎仔10 分钟前
LeetCode面试HOT100——160. 相交链表
java·学习·算法·leetcode·链表·面试·职场和发展
用户2946555091911 分钟前
游戏开发中的向量魔法
后端
敲代码的嘎仔12 分钟前
LeetCode面试HOT100—— 206. 反转链表
java·数据结构·学习·算法·leetcode·链表·面试