`
rensanning
  • 浏览: 3548063 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:38136
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:607280
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:682277
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:89325
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401824
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69685
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91693
社区版块
存档分类
最新评论

Java代码中使用JSP/JSF表达式语言EL

    博客分类:
  • Java
 
阅读更多
JSP/JSF中的“EL”有很多版本,Tomcat对应的EL版本如下:

  • EL2.1:JavaEE5/Tomcat6 (Unified EL:${}和#{}作用相同但不能混用)
  • EL2.2:JavaEE6/Tomcat7
  • EL3.0:JavaEE7/Tomcat8

从JavaEE5开始,EL的package使用javax.el.*。这个EL功能不仅可以使用在JSP/JSF中,也可以使用在所有的Java代码中,el-api.jar、jasper-el.jar可以在Tomcat的lib文件夹中找到,放入自己的工程中即可使用。

(1)EL2.2
这个版本的EL还不怎么支持独立程序使用,用起来也比较复杂。需要用到的几个类:ELContext、FunctionMapper、VariableMapper、ELResolver。

最简单的使用
// (1)Resolver、VariableMapper、FunctionMapper都使用默认实现
final CompositeELResolver resolver = new CompositeELResolver();
resolver.add(new ResourceBundleELResolver());
resolver.add(new MapELResolver());
resolver.add(new ListELResolver());
resolver.add(new ArrayELResolver());
resolver.add(new BeanELResolver());
final VariableMapper varMapper = new VariableMapperImpl();
final FunctionMapper funcMapper = new FunctionMapperImpl();

// (2)创建ELContext
ELContext elContext = new ELContext() {
    @Override
    public ELResolver getELResolver() {
        return resolver;
    }
    @Override
    public FunctionMapper getFunctionMapper() {
        return funcMapper;
    }
    @Override
    public VariableMapper getVariableMapper() {
        return varMapper;
    }
};

// (3)EL表达式工厂类
ExpressionFactory ef = ExpressionFactory.newInstance();

// (4)设置变量的值
varMapper.setVariable("foo", ef.createValueExpression("FOO", String.class));

MyBean myBean = new MyBean();
myBean.setX(1);
myBean.setY(2);
varMapper.setVariable("bar", ef.createValueExpression(myBean, myBean.getClass()));

// (5)读入EL表达式
String expression = "hello, ${foo}! ${bar.x + 234}";// 等价于"hello, #{foo}! #{bar.x + 234}"
ValueExpression ve = ef.createValueExpression(elContext, expression, String.class);

// (6)获取表达式的值
String ret = (String) ve.getValue(elContext);
System.out.println("result=" + ret);// result=hello, FOO! 235

// 更新变量值(对象实例的场合,原有实例的值也会被修改)
String expression2 = "${bar.x}";
ValueExpression ve2 = ef.createValueExpression(elContext, expression2, Object.class);
ve2.setValue(elContext, 123);
System.out.println("myBean.x=" + myBean.getX());// myBean.x=123

// 调用对象实例的方法
String expression31 = "${bar.mes('hello')}";
MethodExpression me1 = ef.createMethodExpression(elContext, expression31, Object.class, new Class[0]);
me1.invoke(elContext, new Object[0]);// mes=hello

String expression32 = "#{bar.mes}";
MethodExpression me2 = ef.createMethodExpression(elContext, expression32, Object.class, new Class[] {String.class});
me2.invoke(elContext, new Object[] {"hello"});// mes=hello

public class MyBean {
	private int x;

	private int y;

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public void mes(String mes) {
		System.out.println("mes=" + mes);
	}

	@Override
	public String toString() {
		return "(x: " + x + ", y:" + y + ")";
	}
}


设置预定义变量
final CompositeELResolver resolver = new CompositeELResolver();
resolver.add(new ResourceBundleELResolver());
resolver.add(new MapELResolver());
resolver.add(new ListELResolver());
resolver.add(new ArrayELResolver());
resolver.add(new BeanELResolver());
resolver.add(new MyImplicitELResolver());// *****添加自定义Resolver*****
final VariableMapper varMapper = new VariableMapperImpl();
final FunctionMapper funcMapper = new FunctionMapperImpl();

ELContext elContext = new ELContext() {
    @Override
    public ELResolver getELResolver() {
        return resolver;
    }
    @Override
    public FunctionMapper getFunctionMapper() {
        return funcMapper;
    }
    @Override
    public VariableMapper getVariableMapper() {
        return varMapper;
    }
};

ExpressionFactory ef = ExpressionFactory.newInstance();

List<String> lst = Arrays.asList("aaa", "bbb", "ccc", "ddd");
varMapper.setVariable("list", ef.createValueExpression(lst, List.class));

// 包含预定义变量implicit的EL表达式
String expression = "${list[implicit.idx]}";
ValueExpression ve = ef.createValueExpression(elContext, expression, String.class);

// 设置预定义变量implicit的Context
ImplicitContext implicitContext = new ImplicitContext();
elContext.putContext(ImplicitContext.class, implicitContext);

for (int idx = 0; idx < lst.size(); idx++) {
    implicitContext.put("idx", Integer.valueOf(idx));
    String ret = (String) ve.getValue(elContext);
    System.out.println("ret[" + idx + "]=" + ret);
}
// ret[0]=aaa
// ret[1]=bbb
// ret[2]=ccc
// ret[3]=ddd

public class ImplicitContext extends HashMap<String, Object> {}
public class MyImplicitELResolver extends ELResolver {
	
	@Override
    public Class<?> getCommonPropertyType(ELContext context, Object base) {
        if (base == null) {
            return String.class;
        }
        return null;
    }

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(
            ELContext context, Object base) {
        if (base != null) {
            return Collections.<FeatureDescriptor>emptyList().iterator();
        }
        return null;
    }

    @Override
    public Class<?> getType(ELContext context, Object base, Object property) {
        if (base == null && property != null) {
            String name = property.toString();
            if ("implicit".equals(name)) {
                context.setPropertyResolved(true);
                return ImplicitContext.class;
            }
        }
        return null;
    }

    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null && property != null) {
            String name = property.toString();
            if ("implicit".equals(name)) {
                context.setPropertyResolved(true);
                return context.getContext(ImplicitContext.class);
            }
        }
        return null;
    }

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

    @Override
    public void setValue(ELContext context, Object base, Object property, Object value) {
        throw new PropertyNotWritableException("base=" + base + "/property=" + property);
    }

}


自定义函数

final CompositeELResolver resolver = new CompositeELResolver();
resolver.add(new ResourceBundleELResolver());
resolver.add(new MapELResolver());
resolver.add(new ListELResolver());
resolver.add(new ArrayELResolver());
resolver.add(new BeanELResolver());
final VariableMapper varMapper = new VariableMapperImpl();

// *****定义FunctionMapper*****
final FunctionMapper funcMapper = new FunctionMapper() {
    private HashMap<String, Method> methods = new HashMap<String, Method>();
    {
        for (Method method : Math.class.getMethods()) {
            if (Modifier.isStatic(method.getModifiers())) {
                String name = method.getName();
                Class<?>[] params = method.getParameterTypes();
                boolean accept = true;
                if (params.length > 0) {
                    if (!params[0].isAssignableFrom(double.class)) {
                        accept = false;
                    }
                }
                if (accept) {
                    methods.put(name, method);
                }
            }
        }
    }
    
    @Override
    public Method resolveFunction(String prefix, String localName) {
        if ("math".equals(prefix)) {
            return methods.get(localName);
        }
        return null;
    }
};

ELContext elContext = new ELContext() {
    @Override
    public ELResolver getELResolver() {
        return resolver;
    }
    @Override
    public FunctionMapper getFunctionMapper() {
        return funcMapper;
    }
    @Override
    public VariableMapper getVariableMapper() {
        return varMapper;
    }
};

ExpressionFactory ef = ExpressionFactory.newInstance();

varMapper.setVariable("a", ef.createValueExpression(10, Integer.class));
varMapper.setVariable("b", ef.createValueExpression(20, Integer.class));

String expression = "max=${math:max(a,b)}, min=${math:min(a,b)}";
ValueExpression ve = ef.createValueExpression(elContext, expression, String.class);

String ret = (String) ve.getValue(elContext);
System.out.println("ret=" + ret);// ret=max=20.0, min=10.0	


(2)EL3.0
在最新版的EL3.0中,Java代码中可以通过ELProcessor来很简单的使用EL。
ELProcessor elProc = new ELProcessor();

// 设置变量
elProc.defineBean("foo", new BigDecimal("123"));
elProc.defineBean("bar", "brabrabra");

// 获取表达式的值getValue()
String expression = "bar += '☆' += foo"; // 不需要使用${}或#{}
String ret1 = (String)elProc.getValue(expression, String.class);
System.out.println("ret=" + ret1);// ret=brabrabra☆123

// 获取表达式的值eval()
Number ret2 = (Number)elProc.eval("foo + 1");
System.out.println("ret=" + ret2);// ret=124

// 变量的嵌套
elProc.setVariable("v1", "foo * 2");
Number ret3 = (Number)elProc.eval("v1 + 1");
System.out.println("ret=" + ret3);// ret=247

Number ret4 = (Number)elProc.eval("v1 + foo");
System.out.println("ret=" + ret4);// ret=369

// 给不存在的变量设置值
elProc.setValue("baz", "1234"); 
Number ret5 = (Number)elProc.eval("baz + 1");
System.out.println("ret=" + ret5);// ret=1235

// 设置其他类型的变量
elProc.eval("qux = [1,2,3,4]");
elProc.eval("map = {'a': 111, 'b': 222}");
System.out.println("qux=" + elProc.getValue("qux", Object.class));// qux=[1, 2, 3, 4]
System.out.println("map=" + elProc.getValue("map", Object.class));// map={b=222, a=111}

// 计算多个表达式
Integer ret6 = (Integer) elProc.getValue("x=1;y=2;z=x+y", Integer.class);
System.out.println("ret=" + ret6);// ret=3

// 静态变量
elProc.defineBean("Color", new ELClass(java.awt.Color.class));
Color color = (Color) elProc.eval("Color.red");
System.out.println("ret=" + color);// ret=java.awt.Color[r=255,g=0,b=0]

// 默认导入了「java.lang.*」
System.out.println("ret=" + elProc.eval("Math.random()"));

// 自定义函数
Method method = MyClass.class.getMethod("strJoin", new Class[] {String.class, List.class});
elProc.defineFunction("myFn", "join", method);
Object ret = elProc.eval("myFn:join(',', ['aaa', 'bbb', 'ccc', 123])");
System.out.println("ret=" + ret);// ret=aaa,bbb,ccc,123

// 计算lambda表达式
List<Integer> listdata = Arrays.asList(1, 2, 3, 4, 5, 6);
elProc.defineBean("list", listdata);

String lambda1 = "sum=0;list.stream().forEach(x->(sum=sum+x));sum";
Number ret8 = (Number) elProc.eval(lambda1); 
System.out.println("ret=" + ret8.intValue());// ret=21

String lambda1b = "list.stream().sum()";
Number ret9 = (Number) elProc.eval(lambda1b); 
System.out.println("ret=" + ret9.intValue());// ret=21

String lambda1c = "list.stream().reduce(0,(a,b)->a+b)";
Number ret10 = (Number) elProc.eval(lambda1c);
System.out.println("ret=" + ret10.intValue());// ret=21

public class MyClass {
    public static String strJoin(String sep, List<Object> args) {
        StringBuilder buf = new StringBuilder();
        if (args != null) {
            for (Object arg : args) {
                if (buf.length() > 0) {
                    buf.append(sep);
                }
                buf.append(arg != null ? arg.toString() : "");
            }
        }
        return buf.toString();
    }
}
  • 大小: 10.1 KB
分享到:
评论
1 楼 qyfn 2014-02-10  
[/color][color=cyan][size=medium][/size][align=center][/align][url][/url][img][/img]
引用

相关推荐

    EL表达式的使用详解

    EL 表达式是一种在 Java 服务器页面(JSP)中使用的表达式语言。它提供了一种简单的方式来访问和操作 Java 对象的属性。EL 表达式广泛应用于 JSP、Servlet、JSF 等 Web 开发技术中。本文将详细介绍 EL 表达式的使用...

    jsp el 表达式语言文档

    在JavaServer Faces(JSF)框架中,EL是默认的表达式语言,用于在视图层和模型层之间传递数据,大大简化了JSF组件的属性绑定。 **八、EL的版本和特性** EL有多个版本,从EL 1.0到EL 3.0,每个版本都引入了新的特性...

    EL表达式的语法介绍

    EL 表达式是 Java 服务器页面(JSP)和 Java 服务器面板(JSF)中使用的一种表达式语言,用于在 Web 应用程序中实现动态内容。EL 表达式可以被解析成数值表达式和方法表达式,其中取值表达式用于引用一个值,而方法...

    表达式与言EL和OGNL

    在Java EE中,EL主要用于JSP和JSF页面,使得在视图层可以方便地访问模型层的数据。 OGNL(Object-Graph Navigation Language),即对象图导航语言,是EL的一种实现,提供了更强大的功能。除了基本的属性访问和方法...

    EL表达式使用详解

    EL表达式(Expression Language),是一种用于Java Web开发中方便数据存取的表达式语言,最初作为JSP标准标签库(JSTL)的一部分,是JSTL 1.0为了方便存取数据而自定义的语言。EL允许开发者在JSP页面中通过简洁的...

    2007年图书:JSP_JSF_Tomcat Web编程从入门到精通

    3. **EL(Expression Language)**:是JSP 2.0引入的表达式语言,简化了在页面中访问JavaBean属性的操作。 **JSF(JavaServer Faces)**是Java EE平台上的用户界面框架,用于构建Web应用程序。JSF的关键特性有: 1...

    EL表达式所需要的jar包

    EL表达式语言简化了从视图层到模型层的数据传递,使得开发者在JSP页面中能够更加专注于页面的展示逻辑,而不是复杂的Java代码。 在这个“EL表达式所需要的jar包”压缩文件中,通常包含的是用于支持EL表达式执行所需...

    个人CSS、EL表达式、HTML、jsp笔记

    EL(Expression Language)是Java服务器页面(JSP)中的一个表达式语言,用于访问JavaBeans组件的属性并执行基本运算。它简化了从JSP页面获取和设置Java对象的属性的过程。EL表达式通常在`${}`中写,例如`${user....

    JXL使用模板通过el表达式生成excel文件

    EL(Expression Language)表达式是JavaServer Faces(JSF)中的一种标准表达式语言,用于在Java组件和后台数据之间提供数据绑定和方法调用。在JXL中,结合EL表达式,我们可以动态地生成Excel内容,这使得在模板基础...

    JSF_EL_介绍.doc

    JSF_EL,即JSF表达式语言,是JSF框架内置的一种强大的工具,允许开发者在Web页面中直接访问JavaBeans组件,而无需编写复杂的Java代码。JSF_EL使得组件能够轻松地与后端数据源交互,包括页面Bean、会话Bean和应用程序...

    JSF入门代码

    6. **EL(Expression Language)**:JSF中的EL是一种强大的表达式语言,用于在视图层获取和设置Managed Bean的属性。在"HelloJSF"的JSP/JSF页面中,EL可能被用来显示或收集`HelloBean`中的数据。 7. **部署**:最后...

    EL源代码 java实现

    EL(Expression Language)是Java EE中的一个核心组件,主要用于在JSP、JSF等Web应用程序中简化数据访问和表达式处理。它允许开发者通过简洁的语法来访问和操作Java对象的属性,而无需编写大量的Java脚本或者JSP标签...

    Beginning JSP, JSF and Tomcat_ Java Web Development - Giulio Zambon

    - JSP页面中的数据动态变化部分常使用JSP表达式语言(EL)来访问Java对象。 - JSP生命周期包含页面加载、请求处理和页面卸载等阶段。 ### JSF (JavaServer Faces) - JSF是基于Java的用于构建组件驱动的用户界面的...

    自定义EL表达式

    自定义EL表达式是Java Web开发中的一个高级技巧,它允许开发者扩展标准的JSP Expression Language(EL)功能,以满足特定项目需求。EL是一种简洁的语法,用于在JSP页面中获取JavaBean属性或者调用Java方法。通过...

    jsp,jsF.and tomcat 书籍

    2. JSP表达式语言和JSTL:讲解如何使用EL简化页面逻辑,以及JSTL库在处理流程控制和数据操作中的应用。 3. JSF组件和生命周期:深入理解JSF组件模型,事件处理机制,以及如何进行数据绑定和验证。 4. Facelets和UI...

    EL表达式语法

    例如,在JSF中,组件标签可以使用方法表达式来执行与该标签相关的特定功能。 例如,在上述代码示例中,`...

    JavaServer Faces 2.0完全参考手册(JSF2.0中文版) 1/2

    使用Facelets视图声明语言、托管bean和JSF表达式语言(EL)。按照JSF导航模型声明一个页面,包括新的“隐式导航”功能。使用用户界面组件模型和JSF事件模型,包括支持可添加书签的页面以及POST、REDIRECT、GET模式。...

    Jsf 项目源代码

    4. **表达式语言(EL)**:JSF使用EL来访问JavaBean中的属性,简化了数据绑定。EL表达式可以嵌入在HTML标签中,例如`#{bean.property}`。 5. ** Managed Beans**:在JSF中,Managed Beans是业务逻辑的主要承载者,...

Global site tag (gtag.js) - Google Analytics