这里介绍activiti中的任务管理服务,也就是其中的TaskService。

TaskService功能:

1、对用户任务(UserTask)管理和流程的控制;

2、设置用户任务(UserTask)的权限信息(拥有者,候选人,办理人);

3、针对用户任务添加任务附件、任务评论和事件记录。

TaskService对Task管理与流程控制:

1、Task对象的创建,删除。但是很少使用TaskService手动创建Task,因为一般Task创建通过流程定义。

2、查询Task,并驱动Task节点完成执行。

3、Task相关参数变量(variable)设置。其中本地变量,只能基于TaskId获取,在整个流程过程中使不可变的。

接下去我们开始测试TaskService:

一、首先创建TaskServiceTest测试类与my-process-task.bpmn20.xml流程文件:

具体文件路径如下:

其中my-process-task.bpmn20.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?><definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"><process id="my-process"><startEvent id="start" /><sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" /><userTask id="someTask" name="Activiti is awesome!" activiti:candidateUsers="jjf,user1,user2">   <!-- candidateUsers指定用户 --><documentation>some Task ${message}</documentation>   <!-- Task描述信息,${message}根据传过来message的值替换 --></userTask><sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" /><endEvent id="end" /></process></definitions>

这个流程文件可以获取到someTask的描述信息,message就会根据上下文变量名传过来的message变量值替换。

二、TaskService对Task的查询与设置变量

TaskServiceTest测试类中的测试方法:

    @Test@Deployment(resources = {"my-process-task.bpmn20.xml"})public void testTaskService(){Map<String, Object> variables = Maps.newHashMap();variables.put("message","my test message . . .");activitiRule.getRuntimeService().startProcessInstanceByKey("my-process",variables);   //启动流程TaskService taskService = activitiRule.getTaskService();Task task = taskService.createTaskQuery().singleResult();//获取唯一的当前流程暂停的结点LOGGER.info("task = [{}]" , ToStringBuilder.reflectionToString(task, ToStringStyle.JSON_STYLE));   //使用json格式输出LOGGER.info("task.description = [{}]" , task.getDescription());   //输出配置描述信息taskService.setVariable(task.getId(),"key1","value1");    //给task设置普通变量taskService.setVariableLocal(task.getId(),"localKey1","localValue1");   //给task设置本地变量Map<String, Object> taskServiceVariables = taskService.getVariables(task.getId());    //获取变量Map<String, Object> taskServiceVariablesLocal = taskService.getVariablesLocal(task.getId());    //获取本地变量Map<String, Object> processVariables = activitiRule.getRuntimeService().getVariables(task.getExecutionId());   //根据执行流获取变量LOGGER.info("taskServiceVariables = [{}]",taskServiceVariables);   //{key1=value1, localKey1=localValue1, message=my test message . . .}LOGGER.info("taskServiceVariablesLocal = [{}]",taskServiceVariablesLocal);   //{localKey1=localValue1}LOGGER.info("processVariables = [{}]",processVariables);   //{key1=value1, message=my test message . . .}Map<String,Object> completeVar = Maps.newConcurrentMap();completeVar.put("cKey1","cValue1");taskService.complete(task.getId());   //将流程驱动向下结点执行Task task1 = taskService.createTaskQuery().taskId(task.getId()).singleResult();    //测试看看流程有没有向下执行,若向下执行则为空LOGGER.info("Task = [{}]" , task1);    //null}

输出结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
task = [{"owner":null,"assigneeUpdatedCount":0,"originalAssignee":null,"assignee":null,"delegationState":null,"parentTaskId":null,"name":"Activiti is awesome!","localizedName":null,"description":"some Task my test message . . .","localizedDescription":null,"priority":50,"createTime":"Sat Feb 16 12:21:25 CST 2019","dueDate":null,"suspensionState":1,"category":null,"isIdentityLinksInitialized":false,"taskIdentityLinkEntities":[],"executionId":"6","execution":null,"processInstanceId":"4","processInstance":null,"processDefinitionId":"my-process:1:3","taskDefinitionKey":"someTask","formKey":null,"isDeleted":false,"isCanceled":false,"eventName":null,"currentActivitiListener":null,"tenantId":"","queryVariables":null,"forcedUpdate":false,"claimTime":null,"variableInstances":null,"usedVariablesCache":{},"transientVariabes":null,"cachedElContext":null,"id":"9","revision":1,"isInserted":false,"isUpdated":false,"isDeleted":false}]
task.description = [some Task my test message . . .]
taskServiceVariables = [{key1=value1, localKey1=localValue1, message=my test message . . .}]
taskServiceVariablesLocal = [{localKey1=localValue1}]
processVariables = [{key1=value1, message=my test message . . .}]
Task = [null]Process finished with exit code 0

首先按照json格式输出task信息,然后输出了task的描述信息。在输出全部变量、本地变量、执行流获取的变量。最后将流程执行下去,输出是否还有没有Task事件。

三、TaskService对Task事件权限的配置

TaskService设置Task权限信息:

1、候选用户(candidateUser)和候选组(candidateGroup);

2、指定拥有人(Owner)和办理人(Assignee);

3、通过claim设置办理人。

单元测试方法如下:

    /*** Task事件权限的配置*/@Test@Deployment(resources = {"my-process-task.bpmn20.xml"})public void testTaskServiceUser(){Map<String, Object> variables = Maps.newHashMap();variables.put("message","my test message . . .");activitiRule.getRuntimeService().startProcessInstanceByKey("my-process",variables);   //启动流程TaskService taskService = activitiRule.getTaskService();Task task = taskService.createTaskQuery().singleResult();    //获取唯一的当前流程暂停的结点LOGGER.info("task = [{}]" , ToStringBuilder.reflectionToString(task, ToStringStyle.JSON_STYLE));   //使用json格式输出LOGGER.info("task.description = [{}]" , task.getDescription());   //输出配置描述信息taskService.setOwner(task.getId(),"user1");   //设置task的发起人owner,这里是user1用户//taskService.setAssignee(task.getId(),"jjf");      //设置task事件的代办人,但是没有对属性进行校验,会发生权限冲突,不推荐List<Task> taskList = taskService.createTaskQuery().taskCandidateUser("jjf").taskUnassigned().listPage(0, 100);   //指定了 jjf 候选人,但是taskUnassigned没有被指定某人个for (Task task1:taskList){try{taskService.claim(task1.getId(),"jjf");   //claim时发现指定了代办人则会报错,所以要捕获异常}catch (Exception e){LOGGER.error(e.getMessage(),e);    //打印异常日志}}List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());   //查询指定的task与多少用户相关for (IdentityLink identityLink:identityLinksForTask){LOGGER.info("identityLink = [{}]" , identityLink);}List<Task> tasks = taskService.createTaskQuery().taskAssignee("jjf").listPage(0, 100);  //将用户任务向下继续执行for (Task task1:tasks){Map<String,Object> vars = Maps.newHashMap();vars.put("skey1","cvalue1");taskService.complete(task1.getId(),vars);}LOGGER.info("task是否为空 [{}]", CollectionUtils.isEmpty(tasks));tasks = taskService.createTaskQuery().taskAssignee("jjf").listPage(0, 100);LOGGER.info("task是否为空 [{}]", CollectionUtils.isEmpty(tasks));}

测试结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
task = [{"owner":null,"assigneeUpdatedCount":0,"originalAssignee":null,"assignee":null,"delegationState":null,"parentTaskId":null,"name":"Activiti is awesome!","localizedName":null,"description":"some Task my test message . . .","localizedDescription":null,"priority":50,"createTime":"Thu Dec 27 17:39:32 CST 2018","dueDate":null,"suspensionState":1,"category":null,"isIdentityLinksInitialized":false,"taskIdentityLinkEntities":[],"executionId":"6","execution":null,"processInstanceId":"4","processInstance":null,"processDefinitionId":"my-process:1:3","taskDefinitionKey":"someTask","formKey":null,"isDeleted":false,"isCanceled":false,"eventName":null,"currentActivitiListener":null,"tenantId":"","queryVariables":null,"forcedUpdate":false,"claimTime":null,"variableInstances":null,"usedVariablesCache":{},"transientVariabes":null,"cachedElContext":null,"id":"9","revision":1,"isInserted":false,"isUpdated":false,"isDeleted":false}]
task.description = [some Task my test message . . .]
identityLink = [IdentityLinkEntity[id=10, type=candidate, userId=jjf, taskId=9]]
identityLink = [IdentityLinkEntity[id=12, type=candidate, userId=user1, taskId=9]]
identityLink = [IdentityLinkEntity[id=14, type=candidate, userId=user2, taskId=9]]
identityLink = [IdentityLinkEntity[id=null, type=assignee, userId=jjf, taskId=9]]
identityLink = [IdentityLinkEntity[id=null, type=owner, userId=user1, taskId=9]]
task是否为空 [false]
task是否为空 [true]Process finished with exit code 0

identityLink有五条数据,上面三条有id分别为10,12,14,类型都是candidate候选人,这三条数据都是流程定义文件中设置的,当启动流程时就把这些设置内容序列化到数据库中,作为实体有指定的ID。后面的两条identityLink并没有id,类型是指定的代办人与所有者,就是测试方法中设置的身份。

四、测试Task添加附件

TaskService设置Task附加信息:

1、任务附件(Attachment)创建与查询,上传附件会基于二进制流存储起来;

2、任务评论(Comment)创建与查询;

3、事件记录(Event)创建与查询。

单元测试方法如下:

    /*** 测试Task添加附件(Attachment)*/@Test@Deployment(resources = {"my-process-task.bpmn20.xml"})public void testTaskAttachment(){Map<String, Object> variables = Maps.newHashMap();variables.put("message","my test message . . .");activitiRule.getRuntimeService().startProcessInstanceByKey("my-process",variables);   //启动流程TaskService taskService = activitiRule.getTaskService();Task task = taskService.createTaskQuery().singleResult();//获取唯一的当前流程暂停的结点taskService.createAttachment("url",task.getId(),task.getProcessInstanceId(),"name","description描述","/url/test.png");    //创建一个附件List<Attachment> taskAttachments = taskService.getTaskAttachments(task.getId());for (Attachment taskAttachment : taskAttachments){LOGGER.info("taskAttachment = [{}]",ToStringBuilder.reflectionToString(taskAttachment,ToStringStyle.JSON_STYLE));      //使用json格式输出}}

输出结果如下:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
taskAttachment = [{"name":"name","description":"description描述","type":"url","taskId":"9","processInstanceId":"4","url":"/url/test.png","contentId":null,"content":null,"userId":null,"time":"Fri Dec 28 10:09:52 CST 2018","id":"16","revision":1,"isInserted":false,"isUpdated":false,"isDeleted":false}]Process finished with exit code 0

按照json格式输出附件内容。

五、测试Task添加评论

单元测试方法如下:

    /*** 测试Task添加评论(Comment)*/@Test@Deployment(resources = {"my-process-task.bpmn20.xml"})public void testTaskComment(){Map<String, Object> variables = Maps.newHashMap();variables.put("message","my test message . . .");activitiRule.getRuntimeService().startProcessInstanceByKey("my-process",variables);   //启动流程TaskService taskService = activitiRule.getTaskService();Task task = taskService.createTaskQuery().singleResult();//获取唯一的当前流程暂停的结点taskService.addComment(task.getId(),task.getProcessInstanceId(),"comment 1");    //创建一个评论,参数为事件id  流程实例id  评论内容taskService.addComment(task.getId(),task.getProcessInstanceId(),"comment 2");List<Comment> taskComments = taskService.getTaskComments(task.getId());for (Comment taskComment : taskComments){LOGGER.info("taskComment = [{}]",ToStringBuilder.reflectionToString(taskComment,ToStringStyle.JSON_STYLE));      //使用json格式输出任务评论}}

输出结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
taskComment = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:21:58 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 2","fullMessage":"comment 2","id":"17","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskComment = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:21:58 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 1","fullMessage":"comment 1","id":"16","isInserted":false,"isUpdated":false,"isDeleted":false}]Process finished with exit code 0

六、Task的评论与事件记录比较

    /*** 测试Task添加事件记录(Event)*/@Test@Deployment(resources = {"my-process-task.bpmn20.xml"})public void testTaskEvent(){Map<String, Object> variables = Maps.newHashMap();variables.put("message","my test message . . .");activitiRule.getRuntimeService().startProcessInstanceByKey("my-process",variables);   //启动流程TaskService taskService = activitiRule.getTaskService();Task task = taskService.createTaskQuery().singleResult();//获取唯一的当前流程暂停的结点taskService.setOwner(task.getId(),"user1");   //设置task的发起人owner,这里是user1用户taskService.setAssignee(task.getId(),"jjf");      //设置task事件的代办人taskService.addComment(task.getId(),task.getProcessInstanceId(),"comment 1");    //创建一个评论,参数为事件id  流程实例id  评论内容taskService.addComment(task.getId(),task.getProcessInstanceId(),"comment 2");List<Comment> taskComments = taskService.getTaskComments(task.getId());for (Comment taskComment : taskComments){LOGGER.info("taskComment = [{}]",ToStringBuilder.reflectionToString(taskComment,ToStringStyle.JSON_STYLE));      //使用json格式输出任务评论}List<Event> taskEvents = taskService.getTaskEvents(task.getId());    //获取事件记录for (Event taskEvent : taskEvents){LOGGER.info("taskEvent = [{}]",ToStringBuilder.reflectionToString(taskEvent,ToStringStyle.JSON_STYLE));}}

输出结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
taskComment = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 2","fullMessage":"comment 2","id":"19","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskComment = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 1","fullMessage":"comment 1","id":"18","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskEvent = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 2","fullMessage":"comment 2","id":"19","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskEvent = [{"type":"comment","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":"4","action":"AddComment","message":"comment 1","fullMessage":"comment 1","id":"18","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskEvent = [{"type":"event","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":null,"action":"AddUserLink","message":"jjf_|_assignee","fullMessage":null,"id":"17","isInserted":false,"isUpdated":false,"isDeleted":false}]
taskEvent = [{"type":"event","userId":null,"time":"Fri Dec 28 10:44:38 CST 2018","taskId":"9","processInstanceId":null,"action":"AddUserLink","message":"user1_|_owner","fullMessage":null,"id":"16","isInserted":false,"isUpdated":false,"isDeleted":false}]Process finished with exit code 0

可以看出event的前两条数据与comment数据一样,但是后面两条comment并没有。其实我们可以对useTask做很多操作,操作的过程中event会记录下来,但是comment并不会记录,后两条因为我在测试方法中设置了代办人与拥有人,event都会记录下来。

Activiti6.0流程引擎学习——(22)activiti的任务管理服务(TaskService)相关推荐

  1. Activiti6.0流程引擎学习——(11)使用IDEA编码实现的请假流程

    本篇博客要使用IDEA来实现之前绘制好的请假流程图.流程图如下: 具体创建这个流程图请看这篇博客:https://blog.csdn.net/JJBOOM425/article/details/850 ...

  2. idea安装activiti流程设计器_整合Activiti6.0流程设计器 | 字痕随行

    其它相关的文章索引: 最近一个多月都在尝试了解Activiti6.0,趁着放假整合编辑器这件事情终于有了些眉目,到此可以总结一下了. 第一步:下载源码 整合的时候肯定要从源码拷贝一些东西,有些问题出现 ...

  3. Activiti6.0流程设计器汉化教程(全)

    SpringBoot集成的Activiti6.0代码(绘制工具界面代码 + 审批代码) activiti的modeler汉化. 汉化步骤: 将editor-app--i18n--en.json化后替换 ...

  4. SSM Activiti6.0 工作流引擎 java项目框架 spring5 审批流程

    工作流模块----------------------------------------------------------------------------------------------- ...

  5. 流程引擎课堂(一)| 关于开源流程引擎Activiti 的需要注意的几点

    编者按:流程引擎在各个行业都有应用,其重要性不言而喻,充分了解流程引擎是一项重要课题.本文详细介绍了开源流程引擎Activiti 的优点与局限性,为流程引擎的选型提出了参考性建议. 基础概念 首先,我 ...

  6. Activiti6.0教程 Eclipse安装Activiti Diagram插件(一)

    最近这段时间打算出一个Activiti6.0的详细教程,Activiti作为一个流行的开源工作流引擎,正在不断发展,其6.0版本以API形式提供服务,而之前版本基本都是要求我们的应用以JDK方式与其交 ...

  7. flac3d命令流实例大全_Activiti6.0工作流引擎深度解析

    本课程将系统且深入源码讲解Activiti6.0工作流引擎的使用.配置.核心api以及BPMN2.0规范.数据库设计及模型映射,Spring Boot2.0集成,工作流平台搭建.部署与运维等,通过本课 ...

  8. flowable流程引擎

    Flowable流程引擎 一.流程引擎API和服务 引擎 API 是与 Flowable 交互的最常见方式.主要起点是 ProcessEngine,它可以通过多种方式创建,如配置部分所述.从 Proc ...

  9. 规则引擎和流程引擎我该怎么理解

    流程引擎 什么是流程引擎 流程引擎就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程 ...

最新文章

  1. 测试用例设计之正交表法详解
  2. 【2018年更新】Sublime text 3安装教程(Windows版本)
  3. 开源免费的HTML5游戏引擎
  4. java好学还是ui好学_java编程和ui设计哪个好学?
  5. 互联网巨头基于全球产业链打造ARM CPU
  6. 如何判断一个人是不是值得深入交流?
  7. 1900 页数学基础:面向 CS 的线性代数、拓扑、微积分和最优化
  8. APP设计没有灵感?让那些小众但富有创意的页面告诉你!
  9. linux之service命令
  10. linux下查看当前shell方法。
  11. 【lpxt】笔者支招:九招搞定显示器黑屏
  12. 物流配送管理系统(ssm,mysql)
  13. Ext.grid.EditorGridPanel点击单元格改变数据,动态添加列
  14. Kaggle比赛——预测未来销售(一)
  15. 2022年全球及中国MICC电缆行业运行战略规划与未来投资策略分析报告
  16. numpy的squeeze函数和expand_dims函数
  17. 《K8s与云原生应用》之K8s的系统架构与设计理念
  18. ADS1292R测量心电+呼吸
  19. 软件开发2:代码检视
  20. Ubuntu的版本介绍

热门文章

  1. 【电路】电容(四)——旁路电容
  2. 购买服务器的个人经验
  3. vue项目在ie浏览器中不兼容问题的处理
  4. Java 创建并用应用幻灯片母版
  5. Python基础笔记——函数
  6. 程序猿编程课堂 Python学习之入门篇1:环境搭建与第一个程序
  7. Linux(centos7.9)常用命令大全及基础知识
  8. python入门教程 傻瓜_python傻瓜教程
  9. 分数化小数计算机在线,循环小数化分数计算器
  10. Java化小数为分数_杭电oj1717——小数化分数(java实现)