You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EL Processor中定义带命名空间的变量?

实现EL Processor支持带命名空间的变量

要让EL Processor识别${sys:com.foo.bar}这类带命名空间的变量并解析为System.getProperty的值,你需要自定义ELResolver来实现——defineFunction仅用于注册EL函数,和变量解析逻辑无关。具体步骤如下:

1. 自定义ELResolver类

这个Resolver会拦截指定前缀(比如sys)的变量,将前缀后的部分作为系统属性键获取对应值:

import javax.el.ELContext;
import javax.el.ELResolver;
import java.beans.FeatureDescriptor;
import java.util.Iterator;

public class NamespaceVariableResolver extends ELResolver {
    // 目标命名空间前缀
    private static final String SYS_PREFIX = "sys";

    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        // 处理顶级变量(base为null时对应${prefix:key}格式)
        if (base == null && property instanceof String) {
            String variable = (String) property;
            int colonIndex = variable.indexOf(':');
            if (colonIndex != -1) {
                String prefix = variable.substring(0, colonIndex);
                String propKey = variable.substring(colonIndex + 1);
                if (SYS_PREFIX.equals(prefix)) {
                    // 标记该变量已被处理,避免后续Resolver重复处理
                    context.setPropertyResolved(true);
                    // 返回系统属性值,不存在则返回null
                    return System.getProperty(propKey);
                }
            }
        }
        // 非目标命名空间变量,交给后续Resolver处理
        return null;
    }

    // 以下为必须实现的抽象方法,按默认逻辑处理即可
    @Override
    public Class<?> getType(ELContext context, Object base, Object property) {
        return Object.class;
    }

    @Override
    public void setValue(ELContext context, Object base, Object property, Object value) {
        // 仅处理变量读取,不支持写入,留空即可
    }

    @Override
    public boolean isReadOnly(ELContext context, Object base, Object property) {
        return true;
    }

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
        return null;
    }

    @Override
    public Class<?> getCommonPropertyType(ELContext context, Object base) {
        return String.class;
    }
}

2. 注册自定义Resolver到ELProcessor

创建ELProcessor实例后,将自定义Resolver添加到它的解析器链中:

ELProcessor elProcessor = new ELProcessor();
// 把自定义Resolver放在链的最前面,确保优先处理命名空间变量
elProcessor.getELManager().addELResolver(new NamespaceVariableResolver());

// 测试示例
String userDir = elProcessor.eval("${sys:user.dir}").toString();
System.out.println(userDir); // 输出当前用户工作目录

补充说明

  • 若需支持多个命名空间,可在NamespaceVariableResolver中扩展前缀判断逻辑,添加对应处理分支即可。
  • ELResolver的调用顺序遵循添加顺序,将自定义Resolver放在前面能确保它优先拦截目标变量,避免被默认Resolver提前处理。

内容的提问来源于stack exchange,提问作者user5182503

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 04:20:53