SpringBoot整合Flowable【05】- 使用流程变量传递业务数据

一、前情回顾

在04篇中,我们用代码的形式控制了一个简单的绩效流程的运转,并且基本熟悉了流程运行过程中涉及到的相关表。让我们继续回到这个简单的绩效流程,它依然是有所欠缺的,比如在实际业务场景中,我们在绩效的每个环节都应该有个分数,但目前我们只是指派个人去完成各个节点,并没有输入分数和保存分数的步骤。因此,在今天的文章中,我们将使用Flowable包含的流程变量来管理流程中的自定义数据。

二、认识流程变量

1.定义

首先,我们来看下流程变量的官方定义:在Flowable中,流程变量是在流程实例按步骤执行时需要保存并使用的数据,这些数据被称为变量(variable)。流程实例可以持有变量,这些变量被称为流程变量。

我们目前只需要知道变量可以在Java服务任务中用于调用外部服务(例如为服务调用提供输入或结果存储),参考上面绩效分数的例子。我们在实际业务中执行任何流程都可能涉及到有数据流转,流程变量负责的就是在流程流转的过程中传递业务参数。

2.分类

为了提高使用效率,Flowable将变量分为两种:运行时变量和历史变量:

  • 运行时变量:这是流程实例运行时的变量,存入act_ru_variable表中。在流程实例运行结束时,此实例的变量在表中删除。在流程实例创建及启动时,可以设置流程变量,也可以在流程执行中加入变量。由于流程实例结束时,对应在运行时表的数据跟着被删除,所以,查询一个已经完结流程实例的变量,只能在历史变量表中查找。

  • 历史变量:历史变量存入act_hi_varinst表中。在流程启动时,流程变量会同时存入历史变量表中。这样即使在流程结束时,历史表中的变量仍然存在。这里可以想想前文中的历史流程也是这样,在Flowable的设计中,我们一个流程启动到结束过程中涉及到的所有东西都可以在相应的历史表上查到。

3.类型

一般来说,一个变量由一个名称和值组成,就是个经典的KV结构。K是字符串类型的,V可以是基本数据类型,也可以是个Java对象(Ps:实现了Serializable接口)。如果流程变量名称相同的时候,后一次的值替换前一次的值。

三、使用流程变量

说了这么多,接下来让我们在我们前面定义的绩效流程中加入流程变量的使用,在自评阶段就需要打分,然后上级评和隔级评都需要打分,并且最后隔级评给出的分数权重最大,也就是本次绩效的最终的分数。

1.接口优化

部署流程模型就不赘述了,详情请翻阅04篇,这里主要为了更贴近实际,部署流程后返回流程定义id,这样前端拿到流程定义id也就可以发起请求来启动流程了,这里大家具体看下代码,和原本相比,多了第2步:

@PostMapping("/deploy")
public ResponseEntity<Object> createProcessDef() {
    //1,创建部署对象
    Deployment deployment = repositoryService.createDeployment()
            //2.添加流程定义文件
            .addClasspathResource("process/performance.bpmn20.xml")
            //3.设置流程名称
            .name("绩效流程")
            //4.部署
            .deploy();
    //2.通过流程部署id查询流程定义id
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .deploymentId(deployment.getId()).singleResult();
    //3.返回流程定义id
    return new ResponseEntity<>(new BaseResponse<>(processDefinition.getId()), HttpStatus.OK);
}

2.插入全局流程变量

完成了流程的部署后就可以启动流程了,因为我们在部署成功之后返回了流程定义id,那么这里就可以传参调用了。我们也需要在这时创建这个分数变量,大家可以在这里结合具体场景想想,作为执行层是不是得在完成自评前写好自评分数然后提交。于是我们对原有的启动流程接口进行改造:

/**
 * 启动流程.
 *
 * @return 流程key
 */
@PostMapping("/start/{processId}")
public ResponseEntity<Object> startProcessDef(@PathVariable String processId) {
    //1.启动流程
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);
    //2.维护该流程的分数变量
    runtimeService.setVariable(processInstance.getId(), "score", 0);
    //3.返回流程实例对象id
    return new ResponseEntity<>(new BaseResponse<>(processInstance.getId()), HttpStatus.OK);
}

在原有代码的基础上我们通过runtimeService设置了一个流程变量,这个流程变量是全局的,也就是这个流程没结束的情况下都可以查到并且进行维护,相同key的value会被最新的覆盖,我们执行这个接口后看下act_ru_variable表的变化:
在这里插入图片描述在这里插入图片描述在这张流程变量表上我们可以看到多了一条数据,注意看我圈起来的3个字段:NAMETEXT很明了,就对应着前面的key和value,这个EXECUTION_ID则是我们设置的流程实例ID,如果我们不设置,引擎也会自动生成,我这里只是方便演示这么做的(Ps:不建议自己改,因为当你的流程有分支时,这个执行ID它就是动态的),我们要通过这个执行ID进行对应变量的查询与维护(Ps:再次强调,这张表只负责运行时变量)。

3.维护流程变量

既然在启动流程的时候设置了变量,那么在接下来的每个节点都可以对变量进行更新,从而实现我们提到的需求,通过前面设置的执行ID查询关联的变量,并根据key对value进行维护,代码如下:

@PostMapping("/complete/agentUser/{agentUser}/score/{score}/processInstanceId/{processInstanceId}")
public ResponseEntity<Object> completeTask(@PathVariable String agentUser,
                                           @PathVariable String score,
                                           @PathVariable String processInstanceId) {
    //1.查询指定用户的待办任务
    String agentTaskId = findUserAgentTask(agentUser);
    //2.更新绩效流程变量
    runtimeService.setVariable(processInstanceId, "score", score);
    //3.完成指定任务的审批
    taskService.complete(agentTaskId);
    //4.返回响应
    return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
}

然后使用Apifox进行接口测试,对比04篇这个接口多了两个参数,分别是分数和流程实例ID。我说明下分数在实际场景中肯定是用户填写后由前端传来的;而流程实例ID在前面的启动流程中我们也有返回,所以前端同学也能拿到:
在这里插入图片描述执行成功后,我们再去观察下act_ru_variable表中的那条流程变量,会发现它也同步更新了:
在这里插入图片描述那么我们这里结合实际场景思考下,在我们现在设计的这套流程里,是不是每个节点都能通过流程ID查询并维护这个分数变量从而实现前面提到的业务需求。需要注意的是:我这里只是假设的业务场景,所以各位读者在自己实操的时候要根据自己业务需求来做,这个系列的文章主要目的是尽可能帮各位读者理清各种表的作用和各种API的用法。

4.查询历史变量

当我们这个流程执行结束的时候,act_ru_variable表中的这条数据就消失了:
在这里插入图片描述这时候我们想再查到它就需要到act_hi_varinst表里,也就是流程变量历史表,通过流程ID就可以查到它,那么大家想想如果业务需要查询历史绩效包括分数,是不是就很简单了:
在这里插入图片描述

5.插入局部流程变量

02小标题进行对比,我们发现区别在于一个是全局,另一个是局部。大家观察下前面的部分里的流程变量在这个流程没结束前,任何节点都可以查询和维护,可以理解成它的生命周期伴随着那个流程。但局部流程变量是我们在某个节点声明,一旦这个节点执行过之后,它就和节点的任务一样都只能去历史表里查询了,所以全局和局部最大的区别就是生命周期的不同。

知道了它们的区别,接下来我们看看怎么使用,首先runtimeServicetaskService都可以设置流程变量,这里主要是API的变化,代码如下:

@PostMapping("/complete/agentUser/{agentUser}/score/{score}/processInstanceId/{processInstanceId}")
public ResponseEntity<Object> completeTask(@PathVariable String agentUser,
                                           @PathVariable String score,
                                           @PathVariable String processInstanceId) {
    //1.查询指定用户的待办任务
    String agentTaskId = findUserAgentTask(agentUser);
    //2.更新绩效流程变量
    runtimeService.setVariable(processInstanceId, "score", score);
    //3.设置任务节点流程变量
    taskService.setVariableLocal(agentTaskId, "score2", score);
    //4.完成指定任务的审批
    taskService.complete(agentTaskId);
    //5.返回响应
    return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
}

03处就是在设置局部流程变量,我在完成任务接口上设置了一个任务节点变量,也就是当我执行这个接口后,只能在历史表里看到这条score2的数据,调用接口测试下:
在这里插入图片描述
执行成功后,我们再去act_hi_varinst表查看有没有key为score2的数据:

在这里插入图片描述可以看到此时key为score2的流程变量直接在历史表里,大家需要明白的是,无论是全局流程变量和局部流程变量都需要结合实际业务需求与场景进行使用,我这里只是告诉大家有这么个东西,在项目中怎么用是需要思考的,假设我们当前的这个绩效流程需要查询绩效历史的时候同时展示各个历史节点的分数,大家想想这个局部流程变量是不是就可以派上用场了。但是这也只是一种实现思路,其实用全局流程变量也可以实现,在每个节点设置变量的时候多设置一下,这个新变量在原key的基础上加上任务id,后续它就不会被覆盖了。所以API是很丰富的,主要看大家想怎么用。

6.补充

在这里补充一下,runtimeService也有设置局部流程变量,但传的ID是会影响结果的。如果你传的是流程ID,它就是全局,即使你用这个API;如果你传的是任务ID,它则是关联对应任务的局部流程变量。

runtimeService.setVariableLocal(XXId, "score", score);

四、小结

首先对一直支持该系列的读者表示感谢,同时也对大家表示抱歉,由于近期工作较忙,导致文章更新速度较慢。其实一开始写这个系列只是想让自己回顾下,但是随着慢慢的更新,开始有读者在评论区“催更”,让我看到了这个系列是有价值的,确实可以帮到别人,所以我也会持续更新下去的,给大家打个包票该系列至少更新10篇,尽可能地为大家详细介绍Flowable的用法以及引导大家结合实际业务进行思考。另外,个人水平毕竟有限,如果文章中有错误的地方,也欢迎大家批评指正!

<think>好的,我现在要解决SpringBoot整合Flowable-UI时出现404的问题。首先,我需要回忆一下Flowable-UI的基本配置步骤。记得Flowable-UI需要一些特定的依赖和配置,比如Spring Security的设置,可能还需要正确配置静态资源路径。 用户提到404错误,通常意味着资源未找到或者路由配置不正确。可能的原因包括依赖缺失、路径配置错误、过滤器拦截了请求,或者Spring Security没有正确放行相关路径。 首先检查pom.xml中的依赖是否正确。Flowable-UI通常需要引入flowable-ui-modeler、flowable-ui-common等依赖,同时确保Spring Boot版本兼容。如果依赖版本不匹配,可能导致类加载失败,进而引发404。 然后,查看应用配置文件,比如application.properties,确认是否启用了Flowable的REST API和UI。可能需要设置flowable.rest.app.enabled=true。另外,静态资源的路径可能需要调整,例如设置server.servlet.context-path=/flowable,这样访问路径会变成/flowable/ui,否则默认可能是根路径。 接下来,检查Spring Security配置。Flowable-UI有自己的安全配置,可能需要与项目中的Security配置进行整合。如果自定义了SecurityConfig,可能需要排除Flowable相关的路径,或者允许匿名访问这些路径。例如,在configure方法中添加antMatchers("/flowable-ui/**").permitAll()。 另外,检查日志是否有异常信息,比如Bean创建失败或者路径映射错误。有时候类冲突或缺少必要的Bean会导致UI模块无法正确初始化,从而无法注册控制器,导致404。 还有可能的是Servlet配置问题,比如缺少@ServletComponentScan注解,导致Flowable的Servlet或Filter没有被注册。确保主应用类上有这个注解,或者通过配置类显式注册相关组件。 最后,考虑版本兼容性问题。Spring BootFlowable的版本需要匹配,查看官方文档确认支持的版本。如果版本不兼容,某些类或配置可能无法加载,导致功能失效。 可能需要逐步排查:先确认依赖正确,再检查配置和路径,然后查看安全设置,最后验证版本兼容性。如果这些步骤都正确,可以尝试创建一个最简单的示例项目,逐步添加功能,找出导致404的具体原因。</think>### SpringBoot整合Flowable-UI出现404的解决方案 #### 1. 检查依赖配置 确保`pom.xml`中引入Flowable-UI的核心依赖且版本与SpringBoot兼容: ```xml <dependency> <groupId>org.flowable</groupId> <artifactId>flowable-ui-modeler</artifactId> <version>6.7.2</version> </dependency> ``` **注意**:Flowable 6.x版本需与Spring Boot 2.x配合使用;若使用Spring Boot 3.x需升级到Flowable 7.0+[^1]。 #### 2. 配置静态资源路径 在`application.properties`中添加: ```properties # 启用Flowable REST API flowable.rest.app.enabled=true # 设置上下文路径(避免与现有接口冲突) server.servlet.context-path=/flowable ``` 访问地址将变为:`http://localhost:8080/flowable/ui` #### 3. 安全配置整合 在自定义的`SecurityConfig`类中放行Flowable路径: ```java @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/flowable-ui/**", "/api/**").permitAll() .anyRequest().authenticated() .and().csrf().disable(); } ``` #### 4. 添加Servlet扫描注解 在主启动类添加注解确保Flowable组件加载: ```java @ServletComponentScan("org.flowable.ui") @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 5. 日志排查 检查启动日志中是否包含以下关键信息: ``` Mapped URL path [/flowable-ui] onto handler... Flowable UI applications available at [/ui] ``` 若缺失则说明路由注册失败,需检查Filter配置或依赖冲突。 #### 典型错误场景示例 某开发者因未配置`server.servlet.context-path`导致实际访问路径为`http://localhost:8080/ui`,而服务器预期路径为`http://localhost:8080/flowable/ui`,最终通过明确上下文路径解决404问题[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值