Activiti搭建

时间:2023-03-08 16:21:35

Activiti搭建

前期准备:

JDK+Eclipse+Tomcat+Maven的安装与配置

参考:http://blog.****.net/zhshulin/article/details/30779873

创建一个Maven项目来配置环境

参考:http://blog.****.net/zhshulin/article/details/37921705

1,导入activiti包文件

<activiti-version>5.18.0</activiti-version>

 <!--         activiti依赖包 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti-version}</version>
</dependency>

2、 eclipse安装activiti-designer插件

打开eclipse软件,然后点击菜单栏的help选项,选择install New Software,示例如下:

Activiti搭建

出现如下对话框:

Activiti搭建

点击添加【Add】按钮,出现如下对话框

Activiti搭建

输入如下地址:

Location:http://activiti.org/designer/update/

Name:Activiti

点击OK按钮出现如下窗体:

Activiti搭建

选择Activiti BPMN Desisner,然后一直选择下一步,直到出现如下窗体:

Activiti搭建

如果出现这个窗体,就表明eclipse正在给您下载相应的插件,但是这个办法是在有网的情况下,而且会比较慢,你得耐心等待,

当然还有一个简单的办法,就是我们将下载好的插件放到指定文件夹下。

Activiti搭建

如果能出现,就证明我们的工作流插件就算是安装成功了。

3、spring-activiti.xml配置文件

Activiti搭建

建立spring-activiti.xml配置文件

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/数据库名称" />
<property name="username" value="用户名" />
<property name="password" value="密码" />
<property name="defaultAutoCommit" value="false" />
</bean> <bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="databaseType" value="mysql"/>
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
</bean> <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean> <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" /> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>

4、生成activiti数据表

BaseTestCase.java文件,运行

 package org.projMgr.TestCase;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-activiti.xml"})
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
@Transactional
public class BaseTestCase extends AbstractTransactionalJUnit4SpringContextTests{ @Test
public void test(){
System.out.println ("通导test");
} }

运行结果:

 SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/developing/eclipse/workspace/ProjectManagement/projectManagement/src/main/webapp/WEB-INF/lib/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/Administrator/.m2/repository/org/slf4j/slf4j-log4j12/1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
[org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from class path resource [spring-activiti.xml]
[org.springframework.context.support.GenericApplicationContext] - Refreshing org.springframework.context.support.GenericApplicationContext@5383967b: startup date [Tue Feb 28 18:32:15 CST 2017]; root of context hierarchy
[org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
[org.activiti.engine.impl.db.DbSqlSession] - performing create on engine with resource org/activiti/db/create/activiti.mysql.create.engine.sql
[org.activiti.engine.impl.db.DbSqlSession] - Found MySQL: majorVersion=5 minorVersion=1
[org.activiti.engine.impl.db.DbSqlSession] - performing create on history with resource org/activiti/db/create/activiti.mysql.create.history.sql
[org.activiti.engine.impl.db.DbSqlSession] - Found MySQL: majorVersion=5 minorVersion=1
[org.activiti.engine.impl.db.DbSqlSession] - performing create on identity with resource org/activiti/db/create/activiti.mysql.create.identity.sql
[org.activiti.engine.impl.db.DbSqlSession] - Found MySQL: majorVersion=5 minorVersion=1
[org.activiti.engine.impl.ProcessEngineImpl] - ProcessEngine default created
[org.springframework.test.context.transaction.TransactionalTestExecutionListener] - Began transaction (1) for test context [DefaultTestContext@15eebbff testClass = BaseTestCase, testInstance = org.projMgr.TestCase.BaseTestCase@22d6f11, testMethod = test@BaseTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@30990c1b testClass = BaseTestCase, locations = '{classpath:spring-activiti.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@2453f95d]; rollback [false]
通导test
[org.springframework.test.context.transaction.TransactionalTestExecutionListener] - Committed transaction after test execution for test context [DefaultTestContext@15eebbff testClass = BaseTestCase, testInstance = org.projMgr.TestCase.BaseTestCase@22d6f11, testMethod = test@BaseTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@30990c1b testClass = BaseTestCase, locations = '{classpath:spring-activiti.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
[org.springframework.context.support.GenericApplicationContext] - Closing org.springframework.context.support.GenericApplicationContext@5383967b: startup date [Tue Feb 28 18:32:15 CST 2017]; root of context hierarchy

数据库自动生成25张表:

Activiti搭建

5、测试

在需要存放文件的文件夹右键-new-other,选择activiti diagram

Activiti搭建

设置文件名-next

Activiti搭建

activiti diagram内置了一些 流程定义模板,但是这里我们选择不使用:

Activiti搭建

finish之后出现.bpmn文件:

Activiti搭建

打开这个文件,输入配置信息:

id:流程的唯一标识,建议使用纯英文

Activiti搭建

在设计区域右边找到StartEven,拖进来:

Activiti搭建

设置id、name(这里使用默认,没改)

Activiti搭建

单击左下第二个图标,选择“create user task”

Activiti搭建

设置id、name

Activiti搭建

设置节点分配人:

Activiti搭建

再建两个user task以及EndEvent:

Activiti搭建

右击文件Leave.bpmn选择OpenWith-XML Editor,可查看XML格式文件,将请假申请、销假的节点分配人设置为proposer(可在上一步设置):

Activiti搭建

设置自动生成流程图片:

单击window菜单,选择preference,按下图设置:

Activiti搭建

在原有流程中随意拖动一点,再次保存,即可在同目录下生成png文件:

Activiti搭建

自动生成测试代码:

在Leave.bpmn文件右键-activiti-generate unit test,之后会在test/java/org/activiti/test包中生成ProcessTestLeave.java文件,

把它拉到holleworld文件夹下,修改包路径

ProcessTestLeave.java文件代码,其中filename路径的\需要修改为/:

 package org.holleworld;

 import static org.junit.Assert.*;

 import java.util.HashMap;
import java.util.Map;
import java.io.FileInputStream; import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.ActivitiRule;
import org.junit.Rule;
import org.junit.Test; public class ProcessTestLeave { private String filename = "D:/developing/eclipse/workspace/ProjectManagement/projectManagement/src/test/java/org/holleworld/Leave.bpmn"; @Rule
public ActivitiRule activitiRule = new ActivitiRule(); @Test
public void startProcess() throws Exception {
RepositoryService repositoryService = activitiRule.getRepositoryService();
repositoryService.createDeployment().addInputStream("leave.bpmn20.xml",
new FileInputStream(filename)).deploy();
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("name", "Activiti");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave", variableMap);
assertNotNull(processInstance.getId());
System.out.println("id " + processInstance.getId() + " "
+ processInstance.getProcessDefinitionId());
}
}

run as - JUnitTest,出错......Activiti搭建

 repositoryService.createDeployment().addInputStream("leave.bpmn20.xml",new FileInputStream(filename)).deploy();
这步就跳出,且没有报错信息......尝试
修改leave.bpmn20.xml变成leave.bpmn.xml或者leave.bpmn
修改filename = "org/holleworld/Leave.bpmn";
均无用。

Activiti搭建

另外找到测试代码:

TestActivitiHelloLeave.java

 package org.projMgr.TestCase;

 import java.util.Date;
import java.util.List; import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.junit.Before;
import org.junit.Test; /**
* Activiti入门程序
*
*/
public class TestActivitiHello {
ProcessEngine processEngine = null;
@Before
public void init(){
//自动加载classpath下名为activiti.cfg.xml文件
processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("spring-activiti.xml").buildProcessEngine();
} /** 部署流程定义 */
@Test
public void deploymentProcessDefinitionTest() {
/**
* RepositoryService是Activiti的仓库服务类,流程定义和部署对象相关的Service
* 所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片
*/
RepositoryService repositoryService = processEngine.getRepositoryService();
// 创建一个部署对象DeploymentBuilder,用来定义流程部署的相关参数
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
// 添加部署的名称
deploymentBuilder.name("activiti");
// 添加hello.bpmn和hello.png
deploymentBuilder.addClasspathResource("org/projMgr/TestCase/hello.bpmn");
deploymentBuilder.addClasspathResource("org/projMgr/TestCase/hello.png");
// 部署流程定义
Deployment deployment = deploymentBuilder.deploy(); System.out.println("部署ID:" + deployment.getId());//
System.out.println("部署名称:" + deployment.getName());//activiti入门程序
} // /** 启动流程实例 */
// @Test
// public void startHelloProcessInstanceTest() {
// // 流程定义的key
// String processDefinitionKey = "hello";
// RuntimeService service = processEngine.getRuntimeService();
// /**
// * 使用流程定义的key启动流程实例,key对应hello.bpmn文件中id的属性值,
// * 使用key值启动,默认是按照最新版本的流程定义启动
// */
// ProcessInstance pi = service.startProcessInstanceByKey(processDefinitionKey);
// System.out.println("流程实例ID:" + pi.getId());// 流程实例ID:2501
// // 流程定义ID:hello:1:4
// System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
// } // @Test
// public void setVariables(){
// String taskId = "342504";
// TaskService taskService = processEngine.getTaskService();
// taskService.setVariableLocal(taskId, "请假天数", 3); //与任务ID绑定
// taskService.setVariable(taskId, "请假日期", new Date());
// taskService.setVariable(taskId, "请假原因", "回家看亲");
//
// System.out.println("设置成功了");
// } // /** 查看历史流程实例 */
// @Test
// public void queryHistoricProcessInstanceTest() throws Exception {
// HistoryService service = processEngine.getHistoryService();
//
// // 获取历史流程实例的查询对象
// HistoricProcessInstanceQuery hpiQuery = service.createHistoricProcessInstanceQuery();
// // 设置流程定义KEY
// hpiQuery.processDefinitionKey("hello");
// // 分页条件
// //hpiQuery.listPage(firstResult, maxResults);
// // 排序
// hpiQuery.orderByProcessInstanceStartTime().desc();
//
// // 执行查询
// List<HistoricProcessInstance> hpis = hpiQuery.list();
// // 遍历查看结果
// for (HistoricProcessInstance hpi : hpis) {
// System.out.print("pid:" + hpi.getId() + ",");
// System.out.print("pdid:" + hpi.getProcessDefinitionId() + ",");
// System.out.print("startTime:" + hpi.getStartTime() + ",");
// System.out.print("endTime:" + hpi.getEndTime() + ",");
// System.out.print("duration:" + hpi.getDurationInMillis() + ",");
// System.out.println("vars:" + hpi.getProcessVariables());
// }
// }
//
// /** 查看历史活动实例 */
// @Test
// public void queryHistoricActivityInstanceTest() throws Exception {
// HistoryService service = processEngine.getHistoryService();
// HistoricActivityInstanceQuery haiq=service.createHistoricActivityInstanceQuery();
// //过滤条件
// haiq.processInstanceId("45001");
// // 分页条件
// //haiq.listPage(firstResult, maxResults);
// //排序
// haiq.orderByHistoricActivityInstanceEndTime().asc();
// List<HistoricActivityInstance> hais = haiq.list();
//
// for (HistoricActivityInstance hai : hais) {
// System.out.print("activitiId:" + hai.getActivityId() + ",");
// System.out.print("name:" + hai.getActivityName() + ",");
// System.out.print("type:" + hai.getActivityType() + ",");
// System.out.print("pid:" + hai.getProcessInstanceId() + ",");
// System.out.print("assignee:" + hai.getAssignee() + ",");
// System.out.print("startTime:" + hai.getStartTime() + ",");
// System.out.print("endTime:" + hai.getEndTime() + ",");
// System.out.println("duration:" + hai.getDurationInMillis());
// }
// } // /** 查看历史任务实例 */
// @Test
// public void queryHistoricTaskInstanceTest() throws Exception {
// HistoryService service = processEngine.getHistoryService();
// HistoricTaskInstanceQuery htiq = service.createHistoricTaskInstanceQuery();
// htiq.taskAssignee("李四");
// List<HistoricTaskInstance> tasks = htiq.list();
//
// for (HistoricTaskInstance hti : tasks) {
// System.out.print("pid:" + hti.getProcessInstanceId() + ",");
// System.out.print("assignee:" + hti.getAssignee() + ",");
// System.out.print("startTime:" + hti.getStartTime() + ",");
// System.out.print("endTime:" + hti.getEndTime() + ",");
// System.out.println("duration:" + hti.getDurationInMillis());
// }
// } // /**查询当前人的个人任务*/
// @Test
// public void queryAssigneeTaskTest(){
// //与正在执行的任务管理相关的Service
// TaskService service = processEngine.getTaskService();
// //创建任务查询对象
// TaskQuery query = service.createTaskQuery();
// //指定个人任务查询,指定办理人
// query.taskAssignee("王五");
// List<Task> list = query.list();
// if(list!=null && list.size()>0){
// for(Task task:list){
// System.out.println("任务ID:"+task.getId());
// System.out.println("任务名称:"+task.getName());
// System.out.println("任务的创建时间:"+task.getCreateTime());
// System.out.println("任务的办理人:"+task.getAssignee());
// System.out.println("流程实例ID:"+task.getProcessInstanceId());
// System.out.println("执行对象ID:"+task.getExecutionId());
// System.out.println("流程定义ID:"+task.getProcessDefinitionId());
// }
// }
// } // /**完成个人任务*/
// @Test
// public void completeTaskTest(){
// //任务ID
// String taskId = "50002"; // 需改id
// processEngine.getTaskService()
// .complete(taskId);
// System.out.println("完成任务:任务ID:"+taskId);
// } // /** 删除流程定义 */
// @Test
// public void deleteProcessDefinition() {
// // 使用部署ID,完成删除
// String deploymentId = "27501";
//
// //不带级联的删除 只能删除没有启动的流程,如果流程启动,就会抛出异常
// // processEngine.getRepositoryService().deleteDeployment(deploymentId);
//
// /**
// * 级联删除 不管流程是否启动,都能可以删除
// */
// processEngine.getRepositoryService().deleteDeployment(deploymentId, true);
// System.out.println("删除成功!");
// } }

分步骤测试:

     /** 部署流程定义 */
@Test
public void deploymentProcessDefinitionTest() {
/**
* RepositoryService是Activiti的仓库服务类,流程定义和部署对象相关的Service
* 所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片
*/
RepositoryService repositoryService = processEngine.getRepositoryService();
// 创建一个部署对象DeploymentBuilder,用来定义流程部署的相关参数
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
// 添加部署的名称
deploymentBuilder.name("holleworld");
// 添加hello.bpmn和hello.png
deploymentBuilder.addClasspathResource("org/holleworld/Leave.bpmn");
deploymentBuilder.addClasspathResource("org/holleworld/Leave.png");
// 部署流程定义
Deployment deployment = deploymentBuilder.deploy(); System.out.println("部署ID:" + deployment.getId());//
System.out.println("部署名称:" + deployment.getName());//activiti入门程序
}

运行结果:

Activiti搭建

     /** 启动流程实例 */
@Test
public void startHelloProcessInstanceTest() {
// 流程定义的key
String processDefinitionKey = "leave";
RuntimeService service = processEngine.getRuntimeService();
/**
* 使用流程定义的key启动流程实例,key对应hello.bpmn文件中id的属性值,
* 使用key值启动,默认是按照最新版本的流程定义启动
*/
ProcessInstance pi = service.startProcessInstanceByKey(processDefinitionKey);
System.out.println("流程实例ID:" + pi.getId());// 流程实例ID
// 流程定义ID:hello:1:4
System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
}

运行结果:

Activiti搭建

     /** 查看历史流程实例 */
@Test
public void queryHistoricProcessInstanceTest() throws Exception {
HistoryService service = processEngine.getHistoryService(); // 获取历史流程实例的查询对象
HistoricProcessInstanceQuery hpiQuery = service.createHistoricProcessInstanceQuery();
// 设置流程定义KEY
hpiQuery.processDefinitionKey("leave");
// 分页条件
//hpiQuery.listPage(firstResult, maxResults);
// 排序
hpiQuery.orderByProcessInstanceStartTime().desc(); // 执行查询
List<HistoricProcessInstance> hpis = hpiQuery.list();
// 遍历查看结果
for (HistoricProcessInstance hpi : hpis) {
System.out.print("pid:" + hpi.getId() + ",");
System.out.print("pdid:" + hpi.getProcessDefinitionId() + ",");
System.out.print("startTime:" + hpi.getStartTime() + ",");
System.out.print("endTime:" + hpi.getEndTime() + ",");
System.out.print("duration:" + hpi.getDurationInMillis() + ",");
System.out.println("vars:" + hpi.getProcessVariables());
}
}

运行结果:

Activiti搭建

     /** 查看历史活动实例 */
@Test
public void queryHistoricActivityInstanceTest() throws Exception {
HistoryService service = processEngine.getHistoryService();
HistoricActivityInstanceQuery haiq=service.createHistoricActivityInstanceQuery();
//过滤条件
haiq.processInstanceId("70001");
// 分页条件
//haiq.listPage(firstResult, maxResults);
//排序
haiq.orderByHistoricActivityInstanceEndTime().asc();
List<HistoricActivityInstance> hais = haiq.list(); for (HistoricActivityInstance hai : hais) {
System.out.print("activitiId:" + hai.getActivityId() + ",");
System.out.print("name:" + hai.getActivityName() + ",");
System.out.print("type:" + hai.getActivityType() + ",");
System.out.print("pid:" + hai.getProcessInstanceId() + ",");
System.out.print("assignee:" + hai.getAssignee() + ",");
System.out.print("startTime:" + hai.getStartTime() + ",");
System.out.print("endTime:" + hai.getEndTime() + ",");
System.out.println("duration:" + hai.getDurationInMillis());
}
}

运行结果

Activiti搭建

     /**查询当前人的个人任务*/
@Test
public void queryAssigneeTaskTest(){
//与正在执行的任务管理相关的Service
TaskService service = processEngine.getTaskService();
//创建任务查询对象
TaskQuery query = service.createTaskQuery();
//指定个人任务查询,指定办理人
query.taskAssignee("proposer");
List<Task> list = query.list();
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务的创建时间:"+task.getCreateTime());
System.out.println("任务的办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
}
}
}

运行结果:

Activiti搭建

     /** 查看历史任务实例 */
@Test
public void queryHistoricTaskInstanceTest() throws Exception {
HistoryService service = processEngine.getHistoryService();
HistoricTaskInstanceQuery htiq = service.createHistoricTaskInstanceQuery();
// htiq.taskAssignee("null");
List<HistoricTaskInstance> tasks = htiq.list(); for (HistoricTaskInstance hti : tasks) {
System.out.print("pid:" + hti.getProcessInstanceId() + ",");
System.out.print("assignee:" + hti.getAssignee() + ",");
System.out.print("startTime:" + hti.getStartTime() + ",");
System.out.print("endTime:" + hti.getEndTime() + ",");
System.out.println("duration:" + hti.getDurationInMillis());
}
}

运行结果:
Activiti搭建

     /**完成个人任务*/
@Test
public void completeTaskTest(){
//任务ID
String taskId = "70004"; // 需改id
processEngine.getTaskService()
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
}

运行结果:

Activiti搭建