Activiti6-TaskService(学习笔记)重要
任务管理服务:

可以看出来,TaskService操作对象,主要针对于UserTask,
对于业务方来说,最重要的就是用户任务,可以对用户任务进行增删改查的管理、可以对相关流程的控制、也可以设置一些用户任务的权限信息、也可以针对用户审批中的一些附加信息。

对Task进行输出,看一下其内部的数据格式:
<?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" />-->
<!--定时任务来启动流程-->
<startEvent id="start">
<timerEventDefinition>
<!-- 共执行5次,间隔为10S -->
<timeCycle>R5/PT10S</timeCycle>
</timerEventDefinition>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" /> <!-- 进行修改,如下 -->
<userTask id="someTask" name="Activiti is awesome!"
activiti:candidateUsers="lyf,user1,user2">
<documentation>
some Task ${message}
</documentation>
</userTask> <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" /> <endEvent id="end" /> </process> </definitions>
测试类中输出tostring后的Task,看下它的数据格式:
public class TaskServiceTest {
private static final Logger LOGGER = LoggerFactory.getLogger(RepostoryServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@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();
//将task tostring并输出
LOGGER.info("task = {}", ToStringBuilder.reflectionToString(task, ToStringStyle.JSON_STYLE));
LOGGER.info("task.desctiption = {}",task.getDescription());
}
}
打印输出结果如下:
task = {"owner":null,"assigneeUpdatedCount":,"originalAssignee":null,"assignee":null,"delegationState":null,"parentTaskId":null,"name":"Activiti is awesome!","localizedName":null,"description":"some Task ---my test message!!!-----","localizedDescription":null,"priority":,"createTime":"Thu Apr 11 14:50:55 CST 2019","dueDate":null,"suspensionState":,"category":null,"isIdentityLinksInitialized":false,"taskIdentityLinkEntities":[],"executionId":"","execution":null,"processInstanceId":"","processInstance":null,"processDefinitionId":"my-process:3:15003","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":"","revision":,"isInserted":false,"isUpdated":false,"isDeleted":false}
task.desctiption = some Task ---my test message!!!-----
驱动Task节点完成执行的操作:
taskService.complete(task.getId());
TaskService设置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();
//将task tostring并输出
LOGGER.info("task = {}", ToStringBuilder.reflectionToString(task, ToStringStyle.JSON_STYLE));
LOGGER.info("task.desctiption = {}",task.getDescription()); //指定owner
taskService.setOwner(task.getId(),"user1");
//指定代办人,这种操作会使某个人的待办任务突然消失,被其他人替代
// taskService.setAssignee(task.getId(),"jimmy"); //通过查看已经指定了候选人,但并没有指定确认是某个人办理的情况,
List<Task> taskList = taskService
.createTaskQuery()
.taskCandidateUser("lyf")
.taskUnassigned()
.listPage(0, 100);
//遍历一下
for (Task task1 : taskList) {
try{
taskService.claim(task1.getId(),"lyf");
}catch (Exception e){
LOGGER.error(e.getMessage(),e);
}
} //查询一下指定的task与多少用户相关
List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
//返回的这个list是构建了一个用户或组与一个task 的关系
for (IdentityLink identityLink : identityLinksForTask) {
LOGGER.info("identityLink = {}",identityLink);
} }
测试输出结果:
task = {"owner":null,"assigneeUpdatedCount":,"originalAssignee":null,"assignee":null,"delegationState":null,"parentTaskId":null,"name":"Activiti is awesome!","localizedName":null,"description":"some Task ---my test message!!!-----","localizedDescription":null,"priority":,"createTime":"Thu Apr 11 15:54:39 CST 2019","dueDate":null,"suspensionState":,"category":null,"isIdentityLinksInitialized":false,"taskIdentityLinkEntities":[],"executionId":"","execution":null,"processInstanceId":"","processInstance":null,"processDefinitionId":"my-process:3:20003","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":"","revision":,"isInserted":false,"isUpdated":false,"isDeleted":false}
task.desctiption = some Task ---my test message!!!-----
identityLink = IdentityLinkEntity[id=, type=candidate, userId=lyf, taskId=]
identityLink = IdentityLinkEntity[id=, type=candidate, userId=user1, taskId=]
identityLink = IdentityLinkEntity[id=, type=candidate, userId=user2, taskId=]
identityLink = IdentityLinkEntity[id=null, type=assignee, userId=lyf, taskId=]
identityLink = IdentityLinkEntity[id=null, type=owner, userId=user1, taskId=]
TaskService 设置Task附加信息:

什么情况会用到任务附件(Attachment)呢?
遇到了报销凭证、下班发车电子发票一类的。如果上传附件的话,他是通过一个二进制流存储起来。
任务评论(Comment)呢?
当我提交一个UserTask的时候,除了我们业务上需要的数据,可能还需要加一些备注、评论这些内容也可以基于Task去设置。
事件记录(Event)?
其实对于任务评论还是事件记录它都对应着数据库的一个comment表,只是它们标记的类型有些区别。
任务附件测试类:
@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(); //这里createAttachment()有两种重载,一种是需要输入流,上传附件,另一种是String,url、备注等。
taskService.createAttachment("url",
task.getId(),task.getProcessInstanceId(),
"name","desc","/url/test.png"); //可以做查询操作,从数据库查询出我们附件相关的信息,(ps:task本身的查询没有分页的功能,所以不要给task上传太多附件,增加了压力)
List<Attachment> taskAttachments = taskService.getTaskAttachments(task.getId());
for (Attachment taskAttachment : taskAttachments) {
LOGGER.info("taskAttachment = {}",ToStringBuilder.reflectionToString(taskAttachment,ToStringStyle.JSON_STYLE));
}
}
输出结果如下:
taskAttachment = {"name":"name","description":"desc","type":"url","taskId":"","processInstanceId":"","url":"\/url\/test.png","contentId":null,"content":null,"userId":null,"time":"Thu Apr 11 16:31:07 CST 2019","id":"","revision":,"isInserted":false,"isUpdated":false,"isDeleted":false}
所以可以看到,任务附件这个功能只是对一个实体对象的增加和查询。
下面是测试评论相关的测试类:
@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(); //与附件不同的是 任务评论 这里是addComment方法
taskService.addComment(task.getId(),task.getProcessInstanceId(),"hello 1");
taskService.addComment(task.getId(),task.getProcessInstanceId(),"hello 2"); //做完记录操作以后,就可以进行读取操作了
List<Comment> taskComments = taskService.getTaskComments(task.getId());
for (Comment taskComment : taskComments) {
LOGGER.info("taskComment = {}",ToStringBuilder.reflectionToString(taskComment,ToStringStyle.JSON_STYLE));
} //事件记录相关
//这里直接获取一个事件列表,查看一下它的结构先
List<Event> taskEvents = taskService.getTaskEvents(task.getId());
for (Event taskEvent : taskEvents) {
LOGGER.info("taskEvent = {}",ToStringBuilder.reflectionToString(taskEvent,ToStringStyle.JSON_STYLE));
}
}
输出结果:
taskComment = {"type":"comment","userId":null,"time":"Thu Apr 11 17:00:08 CST 2019","taskId":"27510","processInstanceId":"27505","action":"AddComment","message":"hello 1","fullMessage":"hello 1","id":"27517","isInserted":false,"isUpdated":false,"isDeleted":false}
taskComment = {"type":"comment","userId":null,"time":"Thu Apr 11 17:00:08 CST 2019","taskId":"27510","processInstanceId":"27505","action":"AddComment","message":"hello 2","fullMessage":"hello 2","id":"27518","isInserted":false,"isUpdated":false,"isDeleted":false}
taskEvent = {"type":"comment","userId":null,"time":"Thu Apr 11 17:00:08 CST 2019","taskId":"27510","processInstanceId":"27505","action":"AddComment","message":"hello 1","fullMessage":"hello 1","id":"27517","isInserted":false,"isUpdated":false,"isDeleted":false}
taskEvent = {"type":"comment","userId":null,"time":"Thu Apr 11 17:00:08 CST 2019","taskId":"27510","processInstanceId":"27505","action":"AddComment","message":"hello 2","fullMessage":"hello 2","id":"27518","isInserted":false,"isUpdated":false,"isDeleted":false}
所以可以看出:
对于TaskService有很多操作,在做操作中TaskEvent会去做记录,而TaskComment不会记录,因为在这个单元测试里面,我们只是做了一个评论操作,所以二者输出内容几乎一模一样,但是若用TaskService做一些其他操作,那么TaskEvent会明显比TaskComment 记录的多很多。Task的每一个变化,TaskEvent都会悄悄记录起来。
Activiti6-TaskService(学习笔记)重要的更多相关文章
- Springboot学习笔记(六)-配置化注入
前言 前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而 ...
- activiti学习笔记一
activiti学习笔记 在讲activiti之前我们必须先了解一下什么是工作流,什么是工作流引擎. 在我们的日常工作中,我们会碰到很多流程化的东西,什么是流程化呢,其实通俗来讲就是有一系列固定的步骤 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
随机推荐
- centos7 安装 smplayer
How to setup multimedia on CentOS 7 You will need to also install the EPEL repository as nux-dextop ...
- Docker进阶之八:搭建LNMP网站平台实战
搭建LNMP网站平台实战 LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写.L指Linux,N指Nginx,M一般指MySQL,也可以指MariaDB,P一般指PHP,也可 ...
- 每周分享五个 PyCharm 使用技巧(二)
这是 「PyCharm 技巧分享」系列的第二篇分享.由于上一篇文章得到了大家的一些赞同,所以今天又来给大家推荐一些我平时自己有用的小技巧,大家择需所取即可. 先声明下,并不保证对所有的人都是有帮助的, ...
- 引用KBC.PetroSIM.Interop的dll,在代码中调用时出现 80040154 没有注册类 的错误
失败的尝试: regsvr32注册:模块已加载,但找不到入口点DllRegisterServer regasm注册:需写上regasm的完整路径,注册成功,但问题依旧 将项目的平台改为x86:问题依旧 ...
- Flask实战第3天:url_for使用
我们之前是通过url来找到对应的视图函数 / => hello_world 那么url_for则是通过视图函数找到url hello world => / 演示如下 #c ...
- 生鲜配送管理系统_升鲜宝V2.0 价格组功能 操作说明_15382353715
价格组功能是B端供应链系统,必不可少的一个功能,其主要实现不同的客户不同的价格,B端系统有一个最大的不同就是,有些商品后台下单人员能看到的.有些商品在销售的那一瞬间,还不知道价格.所以这些商品只有后台 ...
- node配置微信小程序解密消息以及推送消息
上一篇文章介绍过 微信小程序配置消息推送,没有看过的可以先去查看一下,这里就直接去把那个客服消息接口去解密那个消息了. 在这里我选择的还是json格式的加密. 也就是给小程序客服消息发送的消息都会被微 ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
- 数据库原理 - 序列7 - Binlog与主从复制
本文节选自作者书籍<软件架构设计:大型网站技术架构与业务架构融合之道>.作者微信公众号:架构之道与术.公众号底部菜单有书友群可以加入,与作者和其他读者进行深入讨论.也可以在京东.天猫上购买 ...
- 【Spring Cloud笔记】 Eureka通过集群实现高可用
Eureka实现服务注册与发现,在Spring Cloud微服务中起着关键性的作用,必须保障其高可用,常规方案无非通过集群实现.这里在本地机器搭建一个伪集群环境,通过两个节点实现相互注册,并通过主备数 ...