SpringBoot MVEL 表达式

MVEL 是一个表达式语言,一般用于解析和执行基于 Java 基础语言和语法风格的表达式。在动态规则执行和条件匹配方面,MVEL 是一个出色的选择,因为它允许你在运行时定义和修改规则,并立即处理这些规则。

一个常见的案例是用 MVEL 规则引擎对一组商品进行定价。你可能会定义一些如下的规则:

java

String rule = "item.price > 1000 ? item.price * 0.9 : item.price";

这个规则表明了如果商品价格大于 1000,那么该商品的价格就打 9 折。这些规则不是在代码中硬编码的,而是可以在运行时更改的,这给了你更大的灵活性。

要执行这样的规则,你首先需要一个商品对象:

java

public class Item {
    private double price;

    public Item(double price) {
        this.price = price;
    }

    // getter 和 setter 方法
}

你可以创建一个新的商品实例,并设置其价格:

java

Item item = new Item(1200);

然后,你就可以使用 MVEL 执行规则了:

java

Map<String,Object> vars = new HashMap<String,Object>();
vars.put("item", item);
Object discountedPrice = MVEL.eval(rule, vars);

在这个例子中,规则被当作字符串进行处理,而其中的 item 变量被用于规则表达式中,作为上下文数据的一部分提供给 MVEL。

这样做的好处是,你可以在运行时根据需要更改或增加规则,而无需修改并重新编译源代码。并且,通过使用 MVEL,你可以拥有接近 Java 的语法和性能,同时仍然拥有脚本语言的灵活性。

首先,你需要将 MVEL 引入您的 Spring Boot 项目,只需将下表依赖添加到 Maven pom.xml 文件中:

<dependency>
    <groupId>org.mvel</groupId>
    <artifactId>mvel2</artifactId>
    <version>2.4.12.Final</version>
</dependency>

一旦 MVEL 在你的 Spring Boot 项目中,你就可以像以下示例一样使用它:

import org.mvel2.MVEL;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Service
public class MvelExpressionEvalService {

    public boolean evaluate(String expression, Map<String, Object> variables) {
        return MVEL.evalToBoolean(expression, variables);
    }
}

在以上的 evaluate 方法中, 我们接受一个表达式字符串和一个映射对象,然后使用 MVEL.evalToBoolean(expression, variables) 对表达式进行计算。对于更复杂的情况,您可以将一些自定义的函数或其他复杂对象添加到变量映射中,然后在 MVEL 表达式中使用它们。

当你想检查一个特定的条件或者运行某个表达式时, 只需调用 MvelExpressionEvalService.evaluate(expression, variables) 方法,其中 variables 是一个包含所有需要在表达式中使用的变量的映射。

你正在使用 MVEL 表达式语言来评估一个表达式。在这里,flight 是一个上下文对象,expression 是一个 string 类型的 MVEL 表达式。

这是一个示例:

import org.mvel2.MVEL;

public class TestMVEL {
    public static void main(String[] args) {
        // 提供一个上下文对象
        Flight flight = new Flight();
        flight.setSeat("101");
        flight.setFlightIndicator("D");
        flight.setAirlineCode("CA");

        // 准备我们的表达式
        String expression = "['101','102','103','104','105','106','106L','106R','108L','108R','110','111','111L','111R','113','114','115','116','117','118','119','120','121','122','123','1234','124','125','126','127','128'].contains(seat) && flightIndicator == 'D' && airlineCode!='MU'";

        // 使用 MVEL 评估 expression
        Boolean result = MVEL.evalToBoolean(expression, flight);

        // 输出结果
        System.out.println("Result: " + result);
    }
}

class Flight {
    private String seat;
    private String flightIndicator;
    private String airlineCode;

    // getters and setters...
}

在这个示例中,我们创建了一个 Flight 类型的上下文对象 flight,然后我们准备了一个字符串 expression 来代表我们的 MVEL 表达式。接着,我们使用 MVEL.evalToBoolean(expression, flight) 来评估这个表达式,结果被存储在 result 变量中。

请注意你需要在 Flight 类中添加合适的 getters 和 setters。同时,你也需要根据你的实际情况修改 expression 和 flight 对象的创建过程。

以上假设你的 表达式是正确的,如果它没有匹配到,可能是因为你的表达式格式不正确,或你的flight 对象没有正确地设置。

MVEL允许在表达式中使用自定义的函数和对象。这使得表达式能够更加灵活和强大。

1. 自定义函数:

MVEL允许您定义自己的函数并在表达式中使用它们。这些函数使用Java的语法,除了在参数列表周围不需要括号。

java

String expression = "doubleTheNumber(10)";

Map<String, Object> vars = new HashMap<String, Object>();
vars.put("doubleTheNumber", new Function() {
    public Integer call(Integer i) {
        return i * 2;
    }
});

Object result = MVEL.eval(expression, vars);
System.out.println(result);  // 输出 20

在上述示例中,我们定义了一个名为doubleTheNumber的函数,然后在表达式中使用它。

2. 自定义对象:

你也可以在MVEL表达式中使用自己的Java对象。

java

String expression = "foo.doSomething()";

Map vars = new HashMap();

vars.put("foo", new MyObject());

Object result = MVEL.eval(expression, vars);
System.out.println(result);

在这个例子中,我们创建了一个MyObject的实例,MyObject有一个方法doSomething(),然后在表达式中用foo.doSomething()的调用它。

MVEL 包含一些内置函数,以下是一些最常用的函数:

1. strlen(s) : 接受一个字符串 s,返回它的长度。

示例:

java

   int length = (int) MVEL.eval("strlen('hello world')");

2. isdef(variable): 检查给定的变量是否在上下文中定了,并返回一个布尔值。

示例:

java

   Map<String, Object> vars = new HashMap<String, Object>();
   vars.put("myVar", 1);
   System.out.println(MVEL.eval("isdef('myVar')", vars));  // 输出 true

3. isundef(variable): 检查给定的变量是否未在上下文中定义,与 isdef 相反,并返回一个布尔值。

示例:

java

   Map<String, Object> vars = new HashMap<String, Object>();
   vars.put("myVar", 1);
   System.out.println(MVEL.eval("isundef('myVar')", vars));  // 输出 false

4. contains(collection, obj): 检查 collection (如列表、集合等) 是否包含给定的 obj,并返回一个布尔值。

示例:

java

   List<String> list = new ArrayList<>();
   list.add("apple");
   list.add("banana");
   Map<String, List<String>> vars = new HashMap<>();
   vars.put("myList", list);
   System.out.println(MVEL.eval("contains(myList, 'apple')", vars));  // 输出 true

5. soundex(string1, string2): 检查 string1 和 string2 的 soundex(一种接近的发音)是否相等,并返回一个布尔值。

示例:

java

   System.out.println(MVEL.eval("soundex('example', 'egzample')"));  // 输出 true

注意: 在使用内置函数时,最好检查你是否将 MVEL 更新至最新版本,因为一些函数可能只在新版本中可用。

这些只是最常用的一些内置函数,MVEL 还包含其他更复杂的函数,可以参考它的官方文档来了解更多。

MVEL为字符串操作提供了一系列的内置函数:

  1. concat(a, b): 连接字符串 a 和 b
  2. endsWith(s, suffix): 检查字符串 s 是否以后缀 suffix 结尾
  3. startsWith(s, prefix): 检查字符串 s 是否以前缀 prefix 开始
  4. indexOf(s, part): 返回字符串 part 在 s 中第一次出现的索引位置,如果 s 不包含 part,返回 -1
  5. lastIndexOf(s, part): 返回字符串 part 在 s 中最后一次出现的索引位置,如果 s 不包含 part,返回 -1
  6. substring(s, begIndex, endIndex): 返回字符串 s 的子字符串,从 begIndex 到 endIndex
  7. toLowerCase(s): 将字符串 s 中的所有字符转换为小写
  8. toUpperCase(s): 将字符串 s 中的所有字符转换为大写
  9. trim(s): 返回去除了字符串 s 开始和结束的空格的字符串

以下是这些字符串操作的简单示例:

java

Map<String, Object> vars = new HashMap<>();
vars.put("s", "Hello, World!");
System.out.println(MVEL.eval("startsWith(s, 'Hello')", vars));  // 输出 true
System.out.println(MVEL.eval("endsWith(s, '!')", vars));  // 输出 true
System.out.println(MVEL.eval("indexOf(s, ',')", vars));  // 输出 5
System.out.println(MVEL.eval("substring(s, 0, 5)", vars));  // 输出 "Hello"
System.out.println(MVEL.eval("concat('Hi', ' there!')"));  // 输出 "Hi there!"
System.out.println(MVEL.eval("toLowerCase(s)", vars));  // 输出 "hello, world!"
System.out.println(MVEL.eval("toUpperCase(s)", vars));  // 输出 "HELLO, WORLD!"

以上就是 MVEL 在字符串操作上的主要内置函数。对于更复杂规模较大的字符串操作,建议直接在Java代码中进行,然后将结果传递给MVEL表达式。

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值