如何在Activiti中使用瞬态变量

我们昨天发布的Activiti v6 Beta3中已经加入了一个非常需要的功能-临时变量。 在本文中,我将向您展示一个示例,该示例说明如何使用瞬态变量来覆盖一些以前不可能(或最佳)的高级用例。

到目前为止,Activiti中的所有变量都是持久的 。 这意味着将变量和值存储在数据存储中,并保留历史审核数据。 另一方面,瞬态变量的行为和行为类似于常规变量,但它们不会持久存在。 除了不持久之外,以下是瞬态变量的特殊功能:

  • 当流程实例的状态持久保存到数据库时,临时变量将一直保留到下一个“等待状态”。
  • 瞬态变量屏蔽具有相同名称的持久变量。

有关瞬时变量和API的更多详细信息,请参见文档 。

下面显示了用于演示暂态变量的某些位的过程定义。 这是一个非常简单的过程:想法是我们将向用户询问诸如关键字和语言之类的东西,并使用它来进行GitHub API调用。 如果成功,结果将显示给用户。 为此很容易编写一个UI(或使用Beta3 angularJS应用程序中的新表单 ),但是在这篇文章中,我们将只关注代码。

可以在以下Github存储库上找到BPMN 2.0 xml和代码: https : //github.com/jbarrez/transient-vars-example

屏幕截图-自2016-09-01-114450

让我们一起完成整个过程。 该过程首先从用户提供一些有关应搜索内容的输入开始(通常使用开始表格来完成)。

repositoryService.createDeployment().addClasspathResource("process.bpmn20.xml").deploy();Map<String, Object> variables = new HashMap<String, Object>();
variables.put("keyWord", "workflow");
variables.put("language", "java");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("githubsearch", variables);

我们在启动流程实例时传递的变量是常规变量。 它们将被保留,并且将保留审核历史记录,因为没有理由不应该这样做。

执行的第一步是“执行HTTP调用”步骤,这是带有Java委托的服务任务:

<serviceTask name="Execute HTTP call" activiti:class="org.activiti.ExecuteHttpCallDelegate"></serviceTask>

Java代码:

public class ExecuteHttpCallDelegate implements JavaDelegate {public void execute(DelegateExecution execution) {String keyword = (String) execution.getVariable("keyWord");String language = (String) execution.getVariable("language");String url = "https://api.github.com/search/repositories?q=%s+language:%s&sort=starsℴ=desc";url = String.format(url, keyword, language);HttpGet httpget = new HttpGet(url);CloseableHttpClient httpclient = HttpClients.createDefault();try {CloseableHttpResponse response = httpclient.execute(httpget);execution.setTransientVariable("response", IOUtils.toString(response.getEntity().getContent(), "UTF-8"));execution.setTransientVariable("responseStatus", response.getStatusLine().getStatusCode());response.close();} catch (Exception e) {e.printStackTrace();}}}

在这里,我们使用在流程实例启动时传递的'keyword'和'language'变量,针对GitHub API进行了简单的HTTP获取。 这里的特殊之处在于第16和17行,我们将响应和响应状态存储在瞬态变量中(这就是setTransientVariable()调用)。 选择瞬态变量的原因是

  • Github API的json响应非常大。 当然可以以持久的方式存储它,但这对性能不利。
  • 从审计的角度来看,整个响应的意义很小。 稍后,我们将从响应中提取重要的位,并将这些位存储在历史数据中。

得到响应并将其存储在瞬态变量中之后,我们通过排它网关。 序列流如下所示:

<sequenceFlow ... ><extensionElements><activiti:executionListener event="take" class="org.activiti.ProcessResponseExecutionListener"></activiti:executionListener></extensionElements><conditionExpression xsi:type="tFormalExpression"><![CDATA[${responseStatus == 200}]]></conditionExpression>
</sequenceFlow>

请注意,对于顺序流动条件,使用瞬态或非瞬态变量没有区别。 常规的getVariable还将返回带有名称(如果已设置)的瞬态变量(这是上述文档中的阴影部分)。 当只应查询瞬态变量集时,也存在getTransientVariable 。 无论如何:对于条件:完全没有区别。

您还可以看到序列流具有一个(在图中隐藏的)执行侦听器。 执行监听器将解析json响应,选择相关位并将其存储在瞬态数组列表中。 这很重要,因为您将在代码下方阅读。

public class ProcessResponseExecutionListener implements ExecutionListener {private ObjectMapper objectMapper = new ObjectMapper();public void notify(DelegateExecution execution) {List<String> searchResults = new ArrayList<String>();String response = (String) execution.getVariable("response");try {JsonNode jsonNode = objectMapper.readTree(response);JsonNode itemsNode = jsonNode.get("items");if (itemsNode != null && itemsNode.isArray()) {for (JsonNode itemNode : (ArrayNode) itemsNode) {String url = itemNode.get("html_url").asText();searchResults.add(url);}}} catch (IOException e) {e.printStackTrace();}execution.setTransientVariable("searchResults", searchResults);}}

将列表存储为瞬时变量的原因很重要。 如您在图中所看到的,接下来是一个多实例子流程。 子流程通常需要一个集合变量来创建实例。 到目前为止,这是一个持久变量,采用Java序列化 ArrayList的形式。 我从来没有喜欢过它(如果以前必须将委托表达与bean一起使用)。 这总是让我有些困扰。 现在,arraylist是临时的,不会存储在数据存储中:

<subProcess name="subProcess"><multiInstanceLoopCharacteristics isSequential="false" activiti:collection="searchResults" activiti:elementVariable="searchResult" />

请注意,上面的“ searchResult”变量将是一个持久变量。

请注意,在达到用户任务并将状态存储在数据存储中之前,瞬态变量将一直存在。 在启动流程实例时也可以传递瞬态变量(这在这里可以是一种选择,但是我认为存储用户输入是您想要的审计数据内容)。

例如,如果要像这样运行流程实例:

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("keyWord", "workflow");
variables.put("language", "java");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("githubsearch", variables);List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
for (Task task : tasks) {System.out.println("Current task : " + task.getName());
}

作为示例输出(限于5个结果):

当前任务:查看结果https://github.com/Activiti/Activiti
当前任务:查看结果https://github.com/twitter/ambrose
当前任务:查看结果https://github.com/azkaban/azkaban 当前任务:查看结果https://github.com/romannurik/AndroidDesignPreview 当前任务:审查结果https://github.com/spring-projects/spring-xd

用户现在可以查看每个结果的详细信息并继续该过程。

最后的话

您可以想象,瞬时变量有很多用例。 我知道对于许多人来说,这是一个重要的功能,所以我很高兴现在它已经面世了。 像往常一样,当然也欢迎您提供反馈和意见!

翻译自: https://www.javacodegeeks.com/2016/09/use-transient-variables-activiti.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python羊车门问题_「羊车门」经典概率题中不换门选中车的概率是多少?

今天用Python求解「羊车门」经典的概率问题,对概率学基础和Python语法的灵活运用有所收货.本次「羊车门」求解过程采用的是:穷举法计算概率已验证概率学基础理论.期间重点借鉴了奥卡姆剃刀的博客和 南葱&#xff1a;「羊车门」经典概率题中不换门选中车的概率是多少&#xff1f…

非标协议外设LCD1602

概述 LCD1602 &#xff08; Liquid Crystal Display &#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符 (16 列两行) 引脚说明 第 1 脚 : VSS 为电源地 第 2 脚 : VDD 接 5V 正电源 第 3 脚 : VL 为液晶显示器对比度调整端 , 接正电源…

50: Luogu P4568 分层图

分层图最短路模板 #include <iostream> #include <cstdio> #include <cstdlib> #include <ctime> #include <queue> #include <cstring>using namespace std;const int M 2e6 5e5 10;#define gc getchar() inline int read() {int x 0…

C++编程笔记:dll的生成与使用

1.动态链接库&#xff08;dll&#xff09;概述 没接触dll之前觉得它很神秘&#xff0c;就像是一个黑盒子&#xff0c;既不能直接运行&#xff0c;也不能接收消息。它们是一些独立的文件&#xff0c;其中包含能被可执行程序或其他dll调用来完成某项工作的函数&#xff0c;只有在…

如何通过IP地址分辨公网、私网、内网、外网

如何通过IP地址分辨公网、私网、内网、外网内、外网是相对于防火墙而言的&#xff0c;在防火墙内部叫做内网&#xff0c;反之就是外网。在一定程度上外网等同于公网&#xff0c;内网等同于私网。地址为如下3个区域就是处于私网&#xff1a;1&#xff1a;10.*.*.*2&#xff1a;1…

python画动态表情包_真香!一行Python代码,帮你制作小姐姐的表情包,靠谱吗?...

原标题&#xff1a;真香&#xff01;一行Python代码&#xff0c;帮你制作小姐姐的表情包&#xff0c;靠谱吗&#xff1f;(我的IU女神)对于小姐姐的动态表情包&#xff0c;相必我们大多数人都不会拒绝&#xff0c;而且都会选择默默的将其收藏(不要问我怎么知道的)&#xff0c;一…

mongodb分片

mongodb分片&#xff1a; 本次是用三台主机搭建3个集群&#xff08;主、备、仲裁&#xff09;作为三个分片&#xff0c;一个集群&#xff08;主、备、备&#xff09;做为config服务器&#xff0c;三个mongos单点做路由&#xff0c;每台5个&#xff0c;一共15个。 新建一个mongo…

批量添加PDF帐号目录

本文参考&#xff1a;https://blog.csdn.net/qq_34104395/article/details/78766400然后根据需要整理的。如作者介意请留言&#xff0c;本人会尽快处理&#xff01; 准备材料&#xff1a; 下载工具FreePic2Pdf&#xff08;在本博客上传资料上找PDF转换工具包&#xff09; 找到…

驳斥5条普通流Tropes

我刚读完“ JDK 8收集器的强大功能的一种例外” &#xff0c;我不得不说我很失望。 Java冠军 Simon Ritter是Oracle的前Java推广者&#xff0c;现在是Oracle的Java传播者&#xff0c;现在是Azul Systems的副CTO&#xff08;使用JVM的人 &#xff09;写了它&#xff0c;因此我希…

私网IP如何访问Internet

公网、内网是两种Internet的接入方式。 内网接入方式&#xff1a;上网的计算机得到的IP地址是Inetnet上的保留地址&#xff0c;保留地址有如下3种形式&#xff1a; 10.x.x.x 172.16.x.x至172.31.x.x 192.168.x.x 内网的计算机以NAT&#xff08;网络地址转换&#xf…

钉钉机器人发送图片 python_python封装钉钉Webhook机器人消息发送逻辑

python封装钉钉Webhook机器人消息发送逻辑&#xff0c;目前仅支持python2。安装pip install dingmsgapi初始化实例from ding_msg_api import MsgClient# Webhook机器人access_tokenmsgClient MsgClient("****************")发送Text消息from ding_msg_api import Te…

[LevelDB] 写批处理过程详解

leveldb的write代码初看瞎搞一堆&#xff0c;细看则实为短小精悍。1 Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) { 2  // -----A begin------- 3 Writer w(&mutex_); 4 w.batch my_batch; 5 w.sync options.sync; 6 w.d…

关于excel vba 使用CopyFromRecordset出现格式问题的解决方法

关于excel vba 使用CopyFromRecordset出现格式问题的解决方法 出现问题的写法&#xff1a; With ActiveSheet .Name k(i) For num 1 To UBound(myArray) .Cells(1, num) myArray(num, 1) Next num .rang…

python histo 改变 bins 大小_在Python中显示具有非常不均匀的bin宽度的直方图

这是直方图为了生成这个图,我做了&#xff1a;bins np.array([0.03, 0.3, 2, 100])plt.hist(m, bins bins, weightsnp.zeros_like(m) 1. / m.size)但是,正如您所注意到的,我想绘制每个数据点的相对频率的直方图,只有3个不同大小的区间&#xff1a;bin1 0.03 – > 0.3bin…

parted工具详解

通常我们用的比较多的一般都是fdisk工具来进行分区&#xff0c;但是现在由于磁盘越来越廉价&#xff0c;而且磁盘空间越来越大&#xff1b;而fdisk工具他对分区是有大小限制的&#xff0c;它只能划分小于2T的磁盘。但是现在的磁盘空间很多都已经是远远大于2T了&#xff0c;甚至…

Python安装pyinstaller模块的错误:NO module name “setuptools“

出现改pyinstaller安装错误常见问题是&#xff1a;pip版本或者setuptools包版本过低。 出现上图提示的错误后&#xff0c;升级一下setuptools包&#xff1a; &#xff08;1&#xff09;pip install --upgrade setuptools &#xff08;2&#xff09;pip install pyinstaller

jvm ide_预热JVM –超快速生产服务器和IDE

jvm ide几个月前&#xff0c;我正在阅读Java中的复杂事件处理以及实现低延迟的方法。 在我长达一个小时的研究结束时&#xff0c;我发现即使您的应用程序编写正确并且您的方法主要在0&#xff08;log n&#xff09;的时间内运行&#xff0c;并且您使用的是某些尖端的硬件解决方…

Python 项目打包成可执行程序命令

一、安装pyinstaller (1)winR输入cmd&#xff0c;打开命令窗口 2&#xff09;安装pyinstaller&#xff0c;安装指令&#xff1a;pip install pyinstaller 二、打包 1&#xff0c;切换到打包程序目录 例&#xff1a;需要打包程序目录为&#xff1a;D:\pythonfun\useringfunct…

软RAID-mdadm折腾小记

RAID --- 磁盘阵列,简言之,用来提高硬盘的利用率和速度RAID种类(理论):RAID 0 : 读写性能(最少两块硬盘) --- 硬盘使用量是所有硬盘大小之和,性能是所有硬盘之和RAID 1 : 读写性能,冗余性(最少两块硬盘) --- 空间利用率:所有磁盘中最小的那块(n/2); 读性能接近RAID0,写性能较r…

python学习笔记:第19天 类的约束、异常、MD5和logging

目录 一、类的约束二、异常处理&#xff1a;三、MD5加密四、日志&#xff08;logging模块&#xff09;一、类的约束 真正写写项目的代码时都是多人协作的&#xff0c;所以有些地方需要约束程序的结构。也就是说&#xff0c;在分配任务之前就应该把功能定义好&#xff0c;然后分…