曾经在一个项目中使用表达式来判断处理一些条件,比如订单价格的折扣计算,库存数量的告警线设置等。我们引入了Jexl(一种表达式语言引擎)来处理这些表达式。这里根据几个例子来总结一下它的应用。
例一、算式表达式的处理:
public class jextTest {
public static void main(String[] args) { //数学公式解析和计算 String expression = "(a+b)/c*5"; JexlContext jexlContext = new MapContext(); jexlContext.set("a", 4); jexlContext.set("b", 2); jexlContext.set("c", 2); jexlContext.set("d", 5); Expression e = (Expression) new JexlEngine().createExpression(expression); Number num = (Number) e.evaluate(jexlContext); System.out.println(num); expression = "a || b && c || d"; jexlContext = new MapContext(); jexlContext.set("a", true); jexlContext.set("b", false); jexlContext.set("c", true); jexlContext.set("d", false); org.apache.commons.jexl2.Expression e1 = new JexlEngine().createExpression(expression); Boolean num1 = (Boolean) e1.evaluate(jexlContext); System.out.println(num1); JexlEngine jexl = new JexlEngine(); jexl.setCache(512);//Sets a cache for expressions of the defined size jexl.setLenient(false);//Sets whether this engine considers unknown variables, methods and constructors as errors or evaluates them as null or zero. jexl.setSilent(false); //Sets whether this engine throws JexlException during evaluation when an error is triggered. jexl.setStrict(false); //Sets whether this engine behaves in strict or lenient mode.String calculate = "(a + b) > 10";
e = jexl.createExpression(calculate); JexlContext context = new MapContext(); context.set("a", "3"); context.set("b", "5"); Object res = e.evaluate(context);//silent为false时evaluate方法会抛异常,为true不抛异常但res为null System.out.println(res); }}运行结果如下:
15
truefalse从上例中可以看出,实现一个表达式的解析运算,共涉及到三个主要类:JexlContext、Expression和JexlEngine。
例二、数组取值
ublic class ArrayTest {
public static void main(String[] args) { JexlEngine jexl = new JexlEngine(); JexlContext jc = new MapContext();List l = new ArrayList();
l.add("It is from location 0"); Integer two = new Integer(2); l.add(two); jc.set("array", l);Expression e = jexl.createExpression("array[1]");//从array中取数据
Object o = e.evaluate(jc); System.err.println("Object @ location 1 = " + o);e = jexl.createExpression("array[0]");//从array中取数据
o = e.evaluate(jc); System.err.println("Object @ location 0 = " + o);e = jexl.createExpression("array[0].length()");
o = e.evaluate(jc); System.err.println("The length of the string at location 0 is :" + o); }}运行结果如下:
Object @ location 1 = 2
Object @ location 0 = It is from location 0The length of the string at location 0 is :21例三、取方法运行
public class MethodPropertyTest {
public static void main(String[] args) { JexlEngine jexl = new JexlEngine(); JexlContext jc = new MapContext();MethodPropertyTest foo = new MethodPropertyTest();
Integer number = new Integer(10);jc.set("foo", foo);
jc.set("number", number);Expression e = jexl.createExpression("foo.getFoo()");
Object o = e.evaluate(jc); System.err.println("value returned by the method getFoo() is : " + o);e = jexl.createExpression("foo.convert(1)");
o = e.evaluate(jc); System.err.println("value of " + e.getExpression() + " is : " + o);e = jexl.createExpression("foo.convert(1+7)");
o = e.evaluate(jc); System.err.println("value of " + e.getExpression() + " is : " + o);e = jexl.createExpression("foo.convert(1+number)");
o = e.evaluate(jc); System.err.println("value of " + e.getExpression() + " is : " + o);e = jexl.createExpression("foo.bar");
o = e.evaluate(jc); System.err.println("value returned for the property 'bar' is : " + o); }public String getFoo() {
return "This is from getFoo()"; }public String get(String arg) {
return "This is the property " + arg; }public String convert(long i) {
return "The value is : " + i; }}运行结果如下:
value returned by the method getFoo() is : This is from getFoo()
value of foo.convert(1) is : The value is : 1value of foo.convert(1+7) is : The value is : 8value of foo.convert(1+number) is : The value is : 11value returned for the property 'bar' is : This is the property bar表达式的处理也可以集成Groovy来处理。相比Jexl来讲,Groovy的功能更强大。