Jexl表达式引擎的学习-string语句转java可执行

Java将字符串转换成可执行代码

commons-jexl3新版本

注意区分JexlScript和JexlExpression,

  • JexlExpression可以支持多条语句,并返回最后一句执行结果。
  • JexlExpression支持一条,返回当前条执行结果
  • JexlExpression set = JEXL_ENGINE.createExpression(“pub.aString = value;pub.aString = value;”);

在这里插入图片描述

		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-jexl3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-jexl3</artifactId>
			<version>3.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/junit/junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.13</version>
			<scope>test</scope>
		</dependency>
package com.example.demo1.test7;

import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.JexlScript;
import org.apache.commons.jexl3.MapContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * @author crwu
 */
public class Test2 {


    private static final JexlEngine JEXL_ENGINE = new JexlBuilder().strict(true).silent(false).cache(32).create();

    // some constants
    private static final String LOWER42 = "fourty-two";
    private static final String UPPER42 = "FOURTY-TWO";


    /**
     * An Inner class.
     */
    public static class Inner {
        public static double aDouble = 42.0;
        public static double NOT42 = -42.0;
    }


    /**
     * A Struct, all fields public
     */
    public static class Struct {
        public Inner inner = new Inner();
        public int anInt = 42;
        public String aString = LOWER42;
    }


    // a pub instance
    private Struct pub;
    // the JexlContext to use
    private JexlContext ctxt;

    @Before
    public void setUp() {
        pub = new Struct();
        ctxt = new MapContext();
        ctxt.set("pub", pub);
    }

    @Test
    public void testGetInt() throws Exception {
        JexlExpression get = JEXL_ENGINE.createExpression("pub.anInt");
        Assert.assertEquals(42, get.evaluate(ctxt));
        JEXL_ENGINE.setProperty(pub, "anInt", -42);
        Assert.assertEquals(-42, get.evaluate(ctxt));
    }

    @Test
    public void testSetInt() throws Exception {
        JexlExpression set = JEXL_ENGINE.createExpression("pub.anInt = value");
        ctxt.set("value", -42);
        Assert.assertEquals(-42, set.evaluate(ctxt));
        Assert.assertEquals(-42, JEXL_ENGINE.getProperty(pub, "anInt"));
        ctxt.set("value", 42);
        Assert.assertEquals(42, set.evaluate(ctxt));
        Assert.assertEquals(42, JEXL_ENGINE.getProperty(pub, "anInt"));
        try {
            ctxt.set("value", UPPER42);
            Assert.assertEquals(null, set.evaluate(ctxt));
            Assert.fail("should have thrown");
        } catch (JexlException xjexl) {
            xjexl.printStackTrace();
        }
    }

    @Test
    public void testGetString() throws Exception {
        JexlExpression get = JEXL_ENGINE.createExpression("pub.aString");
        Assert.assertEquals(LOWER42, get.evaluate(ctxt));
        JEXL_ENGINE.setProperty(pub, "aString", UPPER42);
        Assert.assertEquals(UPPER42, get.evaluate(ctxt));
    }

    @Test
    public void testSetString() throws Exception {
        JexlExpression set = JEXL_ENGINE.createExpression("pub.aString = value;");
        ctxt.set("value", UPPER42);
        Assert.assertEquals(UPPER42, set.evaluate(ctxt));
        Assert.assertEquals(UPPER42, JEXL_ENGINE.getProperty(pub, "aString"));
        ctxt.set("value", LOWER42);
        Assert.assertEquals(LOWER42, set.evaluate(ctxt));
        Assert.assertEquals(LOWER42, JEXL_ENGINE.getProperty(pub, "aString"));
    }

    @Test
    public void testGetInnerDouble() throws Exception {
        JexlExpression get = JEXL_ENGINE.createExpression("pub.inner.aDouble");
        Assert.assertEquals(42.0, get.evaluate(ctxt));
        JEXL_ENGINE.setProperty(pub, "inner.aDouble", -42);
        Assert.assertEquals(-42.0, get.evaluate(ctxt));
    }

    @Test
    public void testSetInnerDouble() throws Exception {
        JexlExpression set = JEXL_ENGINE.createExpression("pub.inner.aDouble = value");
        ctxt.set("value", -42.0);
        Assert.assertEquals(-42.0, set.evaluate(ctxt));
        Assert.assertEquals(-42.0, JEXL_ENGINE.getProperty(pub, "inner.aDouble"));
        ctxt.set("value", 42.0);
        Assert.assertEquals(42.0, set.evaluate(ctxt));
        Assert.assertEquals(42.0, JEXL_ENGINE.getProperty(pub, "inner.aDouble"));
        try {
            ctxt.set("value", UPPER42);
            Assert.assertEquals(null, set.evaluate(ctxt));
            Assert.fail("should have thrown");
        } catch (JexlException xjexl) {
        }
    }

    public enum Gender {MALE, FEMALE}


    @Test
    public void testGetEnum() throws Exception {
        ctxt.set("gender", Gender.class);
        String src = "x = gender.MALE;y = gender.FEMALE;";
        JexlScript script = JEXL_ENGINE.createScript(src);
        Object result = script.execute(ctxt);
        // 返回最后一个语句的结果
        System.out.println(result);
        Assert.assertEquals(Gender.MALE, ctxt.get("x"));
        Assert.assertEquals(Gender.FEMALE, ctxt.get("y"));
    }

    @Test
    public void testGetStaticField() throws Exception {
        ctxt.set("Inner", Inner.class);
        String src = "x = Inner.NOT42;y = Inner.aDouble;";
        JexlScript script = JEXL_ENGINE.createScript(src);
        Object result = script.execute(ctxt);
        // 返回最后一个语句的结果
        System.out.println(result);
        Assert.assertEquals(Inner.NOT42, ctxt.get("x"));
        Assert.assertEquals(Inner.aDouble, ctxt.get("y"));
    }
    @Test
    public void testWhile() throws Exception {
        JexlContext jc = new MapContext();
        jc.set("a", 1);
        jc.set("b", "0");
        jc.set("ans", new StringBuffer());
        JexlScript e = JEXL_ENGINE.createScript("while (a < 10) {a = a + 1;ans.append(b);}");
        e.execute(jc);
        System.out.println(jc.get("ans"));
    }

}

commons-jexl老版本

https://blog.csdn.net/weixin_38019299/article/details/85798768

		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-jexl -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-jexl</artifactId>
			<version>2.1.1</version>
		</dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-collections4</artifactId>
			<version>4.4</version>
		</dependency>
package com.example.demo1.test7;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author crwu
 */
public class Test {
    public String getA() {
        return a;
    }
    public void setA(String a) {
        this.a = a;
    }
    private String a;
    private static JexlEngine jexlEngine = new JexlEngine();
    public static void main(String[] args) {
        // t1();
        // t2();
        // t3();
        // t4();
        // t5();
        // t6();
        t7();

    }
    public static void t7() {
        Test tmpTest = new Test();
        tmpTest.setA("1");
        JexlContext jc = new MapContext();
        jc.set("tmpTest", tmpTest);
        jc.set("ans", "");
        Expression e = jexlEngine.createExpression("ans = tmpTest.getA()");
        e.evaluate(jc);
        System.out.println(jc.get("ans"));
        System.out.println("============================");
        e = jexlEngine.createExpression("ans = tmpTest.setA(\"2\")");
        e.evaluate(jc);
        Test tmpTest1 = (Test) jc.get("tmpTest");
        System.out.println(tmpTest1.getA());
    }
    public static void t6() {
        JexlContext jc = new MapContext();
        String str = "一二三四五六七八九十";
        jc.set("Util", new Util());
        jc.set("str", str);
        jc.set("ans", "");
        String expression = "ans = Util.regMatch(\"[\u4e00-\u9fa5]{10,}\",str)";
        Expression e = new JexlEngine().createExpression(expression);
        e.evaluate(jc);
        System.out.println(jc.get("ans"));
    }
    private static void t5() {
        JexlContext jc = new MapContext();
        jc.set("a", 1);
        jc.set("b", "0");
        jc.set("ans", new StringBuffer());
        Expression e = jexlEngine.createExpression("while (a < 10) {a = a + 1;ans.append(b);}");
        e.evaluate(jc);
        System.out.println(jc.get("ans"));
    }
    private static void t4() {
        JexlContext context = new MapContext();//创建Context设值对象
        String expressionStr = "array.size()";//表达式,表达式可以是数组的属性,元素等
        List<Object> array = new ArrayList<Object>();//创建一个列表
        array.add("this is an array");
        array.add(new Integer(0));
        context.set("array", array);//使用context对象将表达式中用到的值设置进去,必须是所有用到的值
        Expression expression = jexlEngine.createExpression(expressionStr);//使用引擎创建表达式对象
        Object o = expression.evaluate(context);//使用表达式对象开始计算
        System.out.println(o);//输出:2
    }

    private static void t3() {
        JexlContext jc = new MapContext();
        jc.set("x", 10);
        jc.set("y", 20);
        Expression e = jexlEngine.createExpression("x - y");
        Object result = e.evaluate(jc);
        System.out.println(result);
    }
    private static void t2() {
        Expression e = jexlEngine.createExpression("10 > 5 && \"test jexl\".contains(\"test\")");
        Object result = e.evaluate(null);
        System.out.println(result);
    }
    private static void t1() {
        Map<String, Object> map = new HashMap<>();
        map.put("alive", "coding every day");
        map.put("err", System.err);
        String expression = "err.print(alive)";
        Test.executeExpression(expression, map);
    }

    public static Object executeExpression(String jexlExpression, Map<String, Object> map) {
        Expression expression = jexlEngine.createExpression(jexlExpression);
        JexlContext context = new MapContext();
        if (MapUtils.isNotEmpty(map)) {
            // map.forEach(context::set);
            map.forEach((s, o) -> context.set(s, o));
        }
        return expression.evaluate(context);
    }
    static class Util {
        public static boolean regMatch(String regEx, String str) {
            Pattern pattern = Pattern.compile(regEx);
            return pattern.matcher(str).matches();
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值