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

相关推荐
Amarantine、沐风倩✨11 分钟前
设计一个监控摄像头物联网IOT(webRTC、音视频、文件存储)
java·物联网·音视频·webrtc·html5·视频编解码·七牛云存储
Kisorge37 分钟前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
啦啦右一1 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
苹果醋32 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
晓纪同学3 小时前
QT-简单视觉框架代码
开发语言·qt
威桑3 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
Hello.Reader3 小时前
深入解析 Apache APISIX
java·apache