Mvel是一种易于使用、灵活且强大的表达式解析器,语法与java有些相似,功能有点像是将我们的自然语言解析为计算机语言(个人通俗理解,不准确)。
基础使用
文档:http://mvel.documentnode.com/#language-guide-for-2.0
举个最简单的例子:
要判断 5 是否大于 2, 或者计算 5减2这种算术运算, 直接用下面代码中写法即可
import org.mvel2.MVEL; import org.mvel2.ParserContext; import java.io.Serializable; / * Mvel测试 * * @author: Danger */ public class MvelTest { public static void main(String[] args) { System.out.println(MVEL.eval("5 > 2")); System.out.println(MVEL.eval("5 - 2")); Serializable expression = MVEL.compileExpression("5 + 2"); Object result = MVEL.executeExpression(expression); System.out.println(result); Object result2 = MVEL.executeExpression(MVEL.compileExpression("[1, 2, 3] contains 2")); System.out.println(result2); } }
其中, MVEL.compileExpression(string)是将表达式编译成mvel可执行的内容,然后通过MVEL.executeExpression(expression)执行。
Mvel表达式是默认支持一些方法的,像是上面例子中用到算术运算、list的contains方法等,同时也支持自定义方法。
自定义方法
某些场景我们需要更复杂的运算或者处理逻辑,这时候可以使用自定义方法。
大致流程:
1. 自定义方法
2. 将自定义方法添加到Mvel的ParserContext中
3. 基于ParserContext环境 编译和执行Mvel表达式
代码如下:
import org.apache.commons.lang3.StringUtils; / * 用户自定义方法 * * @author: Danger */ public class UserFunction { / * 字符串source 是否包含 target, 忽略大小写 * * @param source * @param target * @return boolean */ public static boolean containsIgnCase(String source, String target) { if (StringUtils.isEmpty(source) || StringUtils.isEmpty(target)) { return false; } if (source.toUpperCase().contains(target.toUpperCase())) { return true; } return false; } }
import org.apache.commons.lang3.StringUtils; import org.mvel2.MVEL; import org.mvel2.ParserContext; import java.io.Serializable; import java.lang.reflect.Method; / * Mvel编译 * * @author: Danger */ public class MvelCompiler { private static final MvelCompiler instance = new MvelCompiler(); private static ParserContext context; private MvelCompiler() { context = new ParserContext(); // 将UserFunction类中的所有方法加载到context中 Method[] declaredMethods = UserFunction.class.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { context.addImport(declaredMethod.getName(), declaredMethod); } // 或者用下面这种一个个指定的方式加载到context中 // context.addImport("containsIgnCase", MVEL.getStaticMethod(UserFunction.class, "containsIgnCase", new Class[]{String.class, String.class})); } public static MvelCompiler getInstance() { return instance; } public Serializable compile(String expression) { if (StringUtils.isNotEmpty(expression)) { return MVEL.compileExpression(expression, context); } return null; } }
测试验证:
/ * Mvel测试 * * @author: Danger */ public class MvelTest { public static void main(String[] args) { ParserContext parserContext = new ParserContext(); parserContext.addImport("containsIgnCase", MVEL.getStaticMethod(UserFunction.class, "containsIgnCase", new Class[]{String.class, String.class})); Serializable expression1 = MVEL.compileExpression("containsIgnCase('abc', 'BC')", parserContext); Object result3 = MVEL.executeExpression(expression1); System.out.println(result3); Object result4 = MVEL.executeExpression(MvelCompiler.getInstance().compile("containsIgnCase('abc', 'D')")); System.out.println(result4); } }
以上。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229500.html原文链接:https://javaforall.net
