java字符串执行逻辑或者表达式

我爱海鲸 2023-12-06 19:59:55 暂无标签

简介MVEL、动态编译、规则引擎

碰到一个这样的需求,我们需要通过客户端上传的字符串来进行一个表达式的运算。下面我们来看看怎么实现这一个问题:

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>test2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>liquor</artifactId>
            <version>1.0.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mvel/mvel2 -->
        <dependency>
            <groupId>org.mvel</groupId>
            <artifactId>mvel2</artifactId>
            <version>2.5.1.Final</version>
        </dependency>

    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

测试代码:

package org.example;

import org.mvel2.MVEL;
import org.noear.liquor.DynamicCompiler;
import java.lang.reflect.Method;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception{
        System.out.println(getExpressValueByMvel("20<10||20<=40"));
    }

    public static boolean getExpressValueByMvel(String str) throws Exception {
        return (boolean)MVEL.eval(str);
    }

    public static boolean getExpressValue(String str) throws Exception {
        String className = "com.demo.proxy.MyClass";
        String classCode = "package com.demo.proxy;\n" +
                "\n" +
                "public class MyClass {\n" +
                "\n" +
                "    public boolean bool(){\n" +
                "        return "+str+";" +
                "    }\n" +
                "}";
        DynamicCompiler compiler = new DynamicCompiler();
        compiler.addSource(className, classCode);
        Map<String, Class<?>> classMap = compiler.build();
        Class<?> aClass = classMap.get(className);
        Method method= aClass.getMethod("bool");
        return (boolean)method.invoke(aClass.newInstance());
    }
}

getExpressValue用的是动态编译的一种方式,但是显而易见,太麻烦了,而且性能也不强(具体我也没测试过)

getExpressValueByMvel用的是规则引擎的一种方式。从上面的代码来看我们能够发现非常的简单。

参考文章:

MVEL2.0表达式使用指南

你好:我的2025