flowable 实现 流程表达式 校验

场景:工作流在配置分支的时候,需要配置流条件,而流条件有时候会比较复杂,容易写错。本章主要描述 如何从 flowable 源码中拿到 表达式处理代码。

环境
springboot:2.2.0.RELEASE
flowable:6.4.2

测试流程图

如上图,表达式的写法可以很多用,flowable会基于spring EL 表达式的基础上,再进行扩展:

到节点A:(自定义函数)流条件:

${variables:substr(a1,index1,end1)}=='哈哈'} 

到节点B:(数字比较)流条件:

${b==2}

到节点C:(字符串对象方法)流条件:

${c.contains("BCD")}

所以如果要进行 flowable 表达式 校验,就需要模拟拿到核心。

从源码中可以找到类:org.flowable.engine.impl.util.condition.ConditionUtil

            Expression expression = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager().createExpression(conditionExpression);
            Condition condition = new UelExpressionCondition(expression);
            return condition.evaluate(sequenceFlow.getId(), execution);

通过Debug,可以找到实现类:
org.flowable.spring.SpringExpressionManager
org.flowable.engine.impl.el.JuelExpression
org.flowable.engine.impl.el.UelExpressionCondition

org.flowable.engine.impl.el.UelExpressionCondition


public class UelExpressionCondition implements Condition {

    protected Expression expression;

    public UelExpressionCondition(Expression expression) {
        this.expression = expression;
    }

    @Override
    public boolean evaluate(String sequenceFlowId, DelegateExecution execution) {
        Object result = expression.getValue(execution);

        if (result == null) {
            throw new FlowableException("condition expression returns null (sequenceFlowId: " + sequenceFlowId + ")" );
        }
        if (!(result instanceof Boolean)) {
            throw new FlowableException("condition expression returns non-Boolean (sequenceFlowId: " + sequenceFlowId + "): " + result + " (" + result.getClass().getName() + ")");
        }
        return (Boolean) result;
    }

}

由上面就可以基本定位到主要代码只有


Expression expression = CommandContextUtil.getProcessEngineConfiguration()
.getExpressionManager()
.createExpression(conditionExpression);

 Object result = expression.getValue(execution);

PS: 前置条件:CommandContextUtil 这一类Utils在flowable中,会在Command获取缓存,直接调回导致 空指针

最终代码为:

package com.example.oldguy.modules.app.plugins;

import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.el.ExpressionManager;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.impl.util.CommandContextUtil;

import java.util.Map;

/**
 * @ClassName: ExpressTestCmd
 * @Author: hrh
 * @Description:
 * @Version:
 **/
public class ExpressTestCmd implements Command {

    private String conditionExpression;
    private Map data;

    public ExpressTestCmd(String conditionExpression, Map data) {
        this.conditionExpression = conditionExpression;
        this.data = data;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager();
        Expression expression = expressionManager.createExpression(conditionExpression);

        DelegateExecution delegateExecution = new ExecutionEntityImpl();
        delegateExecution.setTransientVariables(data);

        return expression.getValue(delegateExecution);
    }
}


测试调用:

@SpringBootTest
public class ExpressTests0924 {

    @Autowired
    private ManagementService managementService;

    @Test
    public void test() {

//        String expression = "${a==1}";
        String expression = "${variables:substr(a1,index1,end1)}${variables:substr(a2,index2)}";
//        String expression = "${substr(a1,index1,end1)}";
        Map data = new HashMap<>();
        data.put("a1", "东方");
        data.put("a", "1");
        data.put("index1", 0);
        data.put("end1", 2);
        data.put("a2", "方不败");
        data.put("index2", 1);

        Object result = managementService.executeCommand(new ExpressTestCmd(expression, data));
        System.out.println(result);
    }

}

返回结果:


image.png

最后在调用异常的时候,需要对异常进行处理(下面只示例参数传输不完整)
org.flowable.common.engine.impl.javax.el.PropertyNotFoundException 传值不完整时候。

image.png

你可能感兴趣的:(flowable 实现 流程表达式 校验)