表达式语言引擎:Apache Commons JEXL 2.1 发布

http://www.linuxde.net/2011/12/4348.html

CommonsJEXL2.1发布了,该版本和2.0.1是二进制兼容的,但源码不兼容,因为新增了两个接口:

org.apache.commons.jexl2.Script

org.apache.commons.jexl2.JexlInfo

JEXL2.1改进内容:

Amorethorougharithmetic(JexlArithmetic)thatallowsfinecontroloverdecimals(scaleandprecision),anewsyntaxfornumericliterals(OGNLinspiredBigandHugenotations)andabettertypehandlingkeepingthemostappropriaterepresentationincasualoperations.

Theintroductionofscriptvariablesandparametersthatreducecontextdependenciesandmethods;thisallowstoperformchecksafterscriptcreation(lightstaticcheckinghints).Plustheabilitytocallscriptfromscripts.

AsandoxingfeaturetorestrictandrenamewhatJEXLcanaccessfromtheenvironmentallowingtightercontroloversecurity.

ExtensionstoUnifiedJEXLthatallowthecreationoftemplates.

完整记录请看:http://commons.apache.org/jexl/changes-report.html#a2.1

JAVAExpressionLanguage(JEXL)是一个表达式语言引擎,可以用来在应用或者框架中使用。JEXL受Velocity和JSP标签库1.1(JSTL)的影响而产生的。需要注意的是,JEXL并不时JSTL中的表达式语言的实现。

下载地址:http://commons.apache.org/jexl/download_jexl.cgi

java实现字符串转换成可执行代码

1.http://wiselyman.iteye.com/blog/1677444

2.http://blog.5ibc.net/p/51238.html

使用commons的jexl可实现将字符串变成可执行代码的功能,我写了一个类来封装这个功能:

import java.util.Map;  
  
import org.apache.commons.jexl2.Expression;  
import org.apache.commons.jexl2.JexlContext;  
import org.apache.commons.jexl2.JexlEngine;  
import org.apache.commons.jexl2.MapContext;  
  
/** 
 * 动态加载方法 
 * @author wangyfc 
 * 
 */  
public class DyMethodUtil {  
      
    public static Object invokeMethod(String jexlExp,Map<String,Object> map){  
        JexlEngine jexl=new JexlEngine();  
        Expression e = jexl.createExpression(jexlExp);  
        JexlContext jc = new MapContext();  
        for(String key:map.keySet()){  
            jc.set(key, map.get(key));  
        }  
        if(null==e.evaluate(jc)){  
            return "";  
        }  
        return e.evaluate(jc);  
    }  
  
}
 

调用方式:

Map<String,Object> map=new HashMap<String,Object>();  
map.put("testService",testService);  
map.put("person",person);  
String expression="testService.save(person)";  
DyMethodUtil.invokeMethod(expression,map);

java中使用jexl进行表达式判断http://hi.baidu.com/leezuu/item/2c98397843284a3c6e29f653

使用el在jsp中很方便,那么在java程序中如何实现表达式判断呢,jexl是个不错的选择

package jexl.test;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine; 
import org.apache.commons.jexl2.MapContext;
public class Tester {
 /**
  * @param args
  */
 public static void main(String[] args) {
  // 描述一个人,他有两条腿
  Map<String, Object> person=new HashMap<String, Object>();
  person.put("skinColor", "red");  // 皮肤为红色
  person.put("age", 23);   // 年龄23
  person.put("cash", 60.8);      // 身上有60.8元现金

  // 左腿定义
  Map<String, Object> leg1=new HashMap<String, Object>();
  leg1.put("leftOrRight", "left");  // 左腿
  leg1.put("length", 20.3);  // 腿长多少
  leg1.put("hair", 3000);  //有多少腿毛
  
  // 右腿定义
  Map<String, Object> leg2=new HashMap<String, Object>();
  leg2.put("leftOrRight", "right");  // 右腿
  leg2.put("length", 20.3);  // 腿长多少
  leg2.put("hair", 3050);  //有多少腿毛
  // 给他两条腿
  List<Map<String, Object> > legs=new ArrayList<Map<String, Object> >();
  legs.add(leg1);
  legs.add(leg2);
  person.put("leg",legs);
  
  // 让这个人变成一个Context,以便Jexl认识他
  JexlContext context = new MapContext(person);
  
  JexlEngine engine=new JexlEngine(); // 定义引擎, 1.1与2.1的用法不同,1.1使用的是工厂
  
  // 看看这个人是否年龄在30岁以上,并且身上有超过100元现金
  boolean yes=(Boolean)engine.createExpression( "age>30 && cash>100" ).evaluate(context); 
  System.out.println("年龄在30岁以上,并且身上有超过100元现金?  "+yes);  // 他没有
  
  // 看看这个人是否左腿上有超过2500根汗毛
  yes=(Boolean)engine.createExpression( "leg[0].hair>2500" ).evaluate(context); 
  
  System.out.println("左腿上有超过2500根汗毛?  "+yes);   // 是的,他有
  
 }
}

结果打印如下

年龄在30岁以上,并且身上有超过100元现金?false

左腿上有超过2500根汗毛?true

上面的例子,如果不知道哪条是左腿呢,这样的表达式该如何写?leg[leftOrRight='left'].hair>2500?

这个写法不会报错,但结果不正确,不知如何实现,求答复

相关推荐