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

相关推荐
01漫游者3 分钟前
JavaScript函数与对象增强知识
开发语言·javascript·ecmascript
GottdesKrieges4 分钟前
OceanBase恢复常见问题
java·数据库·oceanbase
IGAn CTOU4 分钟前
Java高级开发进阶教程之系列
java·开发语言
leo825...8 分钟前
Claude Code Skills 清单(本地)
java·python·ai编程
csbysj202011 分钟前
SQL NULL 函数详解
开发语言
其实防守也摸鱼14 分钟前
CTF密码学综合教学指南--第三章
开发语言·网络·python·安全·网络安全·密码学
NGSI vimp14 分钟前
Java进阶——如何查看Java字节码
java·开发语言
We་ct1 小时前
深度剖析浏览器跨域问题
开发语言·前端·浏览器·跨域·cors·同源·浏览器跨域
身如柳絮随风扬1 小时前
多数据源切换实战:从业务场景到3种实现方案全解析
java·分布式·微服务
skywalk81631 小时前
在考虑双轨制,即在中文语法的基础上,加上数学公式的支持,这样像很多计算将更加简单方便,就像现在的小学数学课本里面一样,比如:定x=2*x + 1
开发语言