0
点赞
收藏
分享

微信扫一扫

java利用JEXL实现动态表达式编译

alanwhy 2024-06-03 阅读 10

实例

maven依赖:

1

2

3

4

5

<

dependency

>


<

groupId

>org.apache.commons

groupId

>


<

artifactId

>commons-jexl

artifactId

>


<

version

>2.0

version

>


dependency

>

正则表达式匹配

首先写一个公共方法:

1

2

3

4

5

6

public

class

Util {


public

static

boolean

regMatch(String regEx, String str) {


Pattern pattern = Pattern.compile(regEx);


return

pattern.matcher(str).matches();


}

}

下面是使用JEXL调用的方法

1

2

3

4

5

6

7

8

9

10

11

public

void

RL() {


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"

));

}

代码中的expression变量就是可以动态编译的表达式,这里要注意表达式中出现的所有变量,都需要事先set进JexlContext中,否则会报错。这里有多种形式的错误:

①如果没有set”Util”,程序运行中会抛出异常。

org.apache.commons.jexl2.JexlException: TmpTest.RL@40![13,40]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' attempting to call method on null

②如果没有set”str”,程序不会抛出异常,并输出null。如果你的regMatch方法中有判空处理,就会输出判空的结果。如果没有判空处理,在控制台的输出如下:

警告: TmpTest.RL@39![36,39]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' undefined variable str二月 21, 2017 4:00:41 下午 org.apache.commons.jexl2.JexlEngine invocationFailed警告: TmpTest.RL@39![13,40]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' method invocation errorjava.lang.NullPointerException

③如果没有set”ans”,程序会正常运行,并输出正确值

为了保险起见,建议表达式中出现的所有变量,都需要事先set进JexlContext中

循环

JEXL支持两种循环方式:

1

2

3

for

(item : list) {


x = x + item;

}

1

2

3

while

(x lt

10

) {


x = x +

2

;

}

下面是使用while的实例:

1

2

3

4

5

6

7

8

9

public

void

loop() {


JexlContext jc =

new

MapContext();


jc.set(

"a"

,

1

);


jc.set(

"b"

,

"0"

);


jc.set(

"ans"

,

new

StringBuffer());


Expression e =

new

JexlEngine().createExpression(

"while (a < 10) {a = a + 1;ans.append(b);}"

);


e.evaluate(jc);


System.out.println(jc.get(

"ans"

));

}

get\set方法调用

JEXL支持传入对象,并调用对象的方法

下面的简单的get\set方法的实例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public

void

getSet() {


TmpTest tmpTest =

new

TmpTest();


tmpTest.setA(

1

);


JexlContext jc =

new

MapContext();


jc.set(

"tmpTest"

, tmpTest);


jc.set(

"ans"

,

""

);


Expression e =

new

JexlEngine().createExpression(

"ans = tmpTest.getA()"

);


e.evaluate(jc);


System.out.println(jc.get(

"ans"

));


e =

new

JexlEngine().createExpression(

"ans = tmpTest.setA(2)"

);


e.evaluate(jc);


TmpTest tmpTest1 = (TmpTest) jc.get(

"tmpTest"

);


System.out.println(tmpTest1.getA());

}

上面的用例会在控制台先输出1,再输出2

举报

相关推荐

0 条评论