Java Expression Language (JEXL) 是一个表达式语言引擎,可以用来在应用或者框架中使用。JEXL 受Velocity 和 JSP 标签库 1.1 (JSTL) 的影响而产生的。需要注意的是, JEXL 并不是 JSTL 中的表达式语言的实现。
实时引擎里
动态逻辑计算分离
计算逻辑经常变化或者可视化逻辑配置
引入Maven包,我这里使用版本最新版本3.2.1版本号。
org.apache.commons
commons-jexl3
3.2.1
通过一个用户在商场购买香蕉、苹果来计算总金额为程序计算场景。苹果5.6一斤、香蕉7.2一斤;用户买2斤苹果,3斤香蕉
JexlBuilder jexlBuilder = new JexlBuilder();
JexlEngine jexlEngine = jexlBuilder.create();
//苹果5.6一斤、香蕉7.2一斤;用户买2斤苹果,3斤香蕉
String expressionStr = "2*5.6+7.2*3";
JexlExpression expression = jexlEngine.createExpression(expressionStr);
MapContext mapContext = new MapContext();
Object evaluate = expression.evaluate(mapContext);
System.out.println(String.format("应支付金额:%s", evaluate));
通过MapContext把表达式需要值传送变量到表达式里,完成用户应付金额。
JexlBuilder jexlBuilder = new JexlBuilder();
JexlEngine jexlEngine = jexlBuilder.create();
//苹果5.6一斤、香蕉7.2一斤;用户买2斤苹果,3斤香蕉
String expressionStr = "applePrice*appleTotal+bananaPrice*bananaTotal";
JexlExpression expression = jexlEngine.createExpression(expressionStr);
MapContext mapContext = new MapContext();
mapContext.set("applePrice", 5.6);
mapContext.set("appleTotal", 2);
mapContext.set("bananaPrice", 7.2);
mapContext.set("bananaTotal", 3);
Object evaluate = expression.evaluate(mapContext);
System.out.println(String.format("用用应支付金额:%s", evaluate));
我们在应该开发时,我们的数据一般封装为JAVA对象,我们在表达式中可以访问与设置对象的值。
JexlBuilder jexlBuilder = new JexlBuilder();
JexlEngine jexlEngine = jexlBuilder.create();
//苹果5.6一斤、香蕉7.2一斤;用户买2斤苹果,3斤香蕉
String expressionStr = "applePrice*appleTotal+bananaPrice*bananaTotal";
JexlExpression expression = jexlEngine.createExpression(expressionStr);
MapContext mapContext = new MapContext();
mapContext.set("applePrice", 5.6);
mapContext.set("appleTotal", 2);
mapContext.set("bananaPrice", 7.2);
mapContext.set("bananaTotal", 3);
Object evaluate = expression.evaluate(mapContext);
System.out.println(String.format("应支付金额:%s", evaluate));
定义商品订单对象为
public class OrderDto implements Serializable {
private Double totalPrice;
private List orderItems;
public Double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
}
public List getOrderItems() {
return orderItems;
}
public void setOrderItems(List orderItems) {
this.orderItems = orderItems;
}
public static class OrderItemDto {
private Double price;
private Integer num;
private String name;
public OrderItemDto(Double price, Integer num, String name) {
this.price = price;
this.num = num;
this.name = name;
}
public OrderItemDto() {
}
public OrderItemDto(Double price, Integer num) {
this.price = price;
this.num = num;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
在业务开发中,我们使用表达式计算不一定满足我们业务需要,我们可以在我们表达式使用自己开发的方法,计算应付金额通过函数来完成。
public class PriceFunction {
/**
* 函数名称
*
* @return 名称
*/
String functionName() {
return "priceFunction";
}
/**
* 计算结果
*
* @param arg 参数
* @return 返回值
*/
public static Object excute(List arg) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
double totalPrice = 0.0D;
for (OrderDto.OrderItemDto dto: arg) {
totalPrice += dto.getPrice() * dto.getNum();
}
return totalPrice;
}
}
计算表达式
JexlBuilder jexlBuilder = new JexlBuilder();
Map functions = new HashMap<>();
functions.put("cacl", new PriceFunction());
jexlBuilder.namespaces(functions);
JexlEngine jexlEngine = jexlBuilder.create();
//苹果5.6一斤、香蕉7.2一斤;用户买2斤苹果,3斤香蕉
OrderDto orderDto = new OrderDto();
List orderItemDtos = new ArrayList<>();
orderItemDtos.add(new OrderDto.OrderItemDto(5.6, 2, "苹果"));
orderItemDtos.add(new OrderDto.OrderItemDto(7.2, 3, "香蕉"));
orderDto.setOrderItems(orderItemDtos);
String expressionStr = "cacl:excute(order.orderItems)";
JexlExpression expression = jexlEngine.createExpression(expressionStr);
MapContext mapContext = new MapContext();
mapContext.set("order", orderDto);
Object evaluate = expression.evaluate(mapContext);
System.out.println(String.format("应支付金额:%s", evaluate));
JexlBuilder jexlBuilder = new JexlBuilder();
JexlEngine jexlEngine = jexlBuilder.create();
//3元表达式
String expressionStr = "(1< 2)? '真':'假'";
JexlExpression expression = jexlEngine.createExpression(expressionStr);
MapContext mapContext = new MapContext();
Object evaluate = expression.evaluate(mapContext);
System.out.println(String.format("结果:%s", evaluate));
JexlBuilder jexlBuilder = new JexlBuilder();
Log log = LogFactory.getLog(JexDemoGrammar.class);
JexlEngine jexlEngine = jexlBuilder.logger(log).create();
//IF判断表达式
String expressionStr = "if(1< 2){ return '真';}else{ return '假';}";
JexlScript expression = jexlEngine.createScript(expressionStr);
MapContext mapContext = new MapContext();
Object evaluate = expression.execute(mapContext);
System.out.println(String.format("结果:%s", evaluate));
//For 循环
String expressionFor = "while (i lt 100) { i = i + 1;total = total + i;}";
JexlScript scriptFor = jexlEngine.createScript(expressionFor);
MapContext context = new MapContext();
context.set("len", 100);
context.set("total", 0);
context.set("i", 0);
context.set("log", log);
Object execute = scriptFor.execute(context);
System.out.println(String.format("结果:%s", execute));