ebuair 2016-11-08
软件环境:开发工具idea,jdk 1.7,tomcat 8.5。
具体web搭建及附件可查看:
项目目录结构如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.activiti.examples</groupId>
<artifactId>activiti-examples</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BPMN 2.0 with Activiti - Examples</name>
<properties>
<activiti-version>5.21.0</activiti-version>
<spring-version>4.3.3.RELEASE</spring-version>
</properties>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-modeler</artifactId>
<exclusions>
<exclusion>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
</exclusion>
</exclusions>
<version>${activiti-version}</version>
</dependency>
<!-- 查看流程详细定义 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-diagram-rest</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-explorer</artifactId>
<exclusions>
<exclusion>
<artifactId>vaadin</artifactId>
<groupId>com.vaadin</groupId>
</exclusion>
<exclusion>
<artifactId>dcharts-widget</artifactId>
<groupId>org.vaadin.addons</groupId>
</exclusion>
<exclusion>
<artifactId>activiti-simple-workflow</artifactId>
<groupId>org.activiti</groupId>
</exclusion>
</exclusions>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.USER_LIBRARY/Activiti Designer
Extensions</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?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/activiti"/>
<property name="username" value="root"/>
<property name="password" value="888"/>
<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"/>
<!--是否在部署时自动生成流程图,默认为true-->
<property name="createDiagramOnDeploy" value="true" />
<!--防止中文乱码-->
<property name="activityFontName" value="宋体"/>
<property name="labelFontName" value="宋体"/>
</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="managementService" factory-bean="processEngine"
factory-method="getManagementService"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>package com.bpm;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.awt.*;
import java.io.*;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-activiti.xml"})
@Rollback
@Transactional
public class BpmDefinitionTest {
@Resource
TaskService taskService;
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
private static Color HIGHLIGHT_COLOR = Color.RED;
private static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(3.0f);
@Test
public void testDeploy() throws IOException {
String sourceFile = "holidayRequest1.bpmn";
/** 发布流程
方法一:流的方式
<code>
InputStream is = new FileInputStream(new File(this.getClass().getResource("/holidayRequest2.bpmn").getPath()));
Assert.assertNotNull(is);
Deployment deployment = repositoryService.createDeployment().addInputStream("bpmn20.xml", is).name("holidayRequest").deploy();
</code>
方法二:当文件在资源目录下时,可使用以下方式直接加载:
*/
Deployment deployment = repositoryService.createDeployment()
.name("helloRequest")
.category("testDemo")
.addClasspathResource(sourceFile).deploy();
Assert.assertNotNull(deployment);
System.out.println("deploymentId:" + deployment.getId());
/**查询流程定义,以下查询方法会自动查询出当前流程的最高版本
* 流程定义主要是用于部署流程的版本控制,在保存部署信息时,会自动先创建一个流程定义。系统会根据*.bpmn中process元素属性来设置数据字段值。
* <code>
* <definitions id="myDef" targetNamespace="testDemo">
* <process id="myProcess" name="My process" >...</process>
* </definitions>
* </code>
* 其中definitions->targetNamespace会作为字段category值,process->id 会作为字段key值,用来标识流程的唯一从而进行版本的自动升级,process->name 会作为字段name值...
* 所以取process id 时要格外注意不要重复了
* */
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
// 获取流程图并生成文件
String diagramResourceName = processDefinition.getDiagramResourceName();
InputStream stream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
// 通过这种方式获取,一定要添加 / ,否则会找不到文件
String path = this.getClass().getResource("/" + sourceFile).getPath();
File file = new File(path);
OutputStream out = new FileOutputStream(file.getParent() + "/holidayRequest.expense.png");
int len;
byte[] data = new byte[1024]; //可以根据实际情况调整,建议使用1024,即每次读1KB
while ((len = stream.read(data)) != -1) {
out.write(data, 0, len); //建议不要直接用os.write(bt)
}
out.flush();
stream.close();
out.close();
/**启动流程实例
* 还可以使用:runtimeService.startProcessInstanceByKey("myProcess");这里的key是定义在bpmn文件中的process元素的id属性
* */
runtimeService.startProcessInstanceById(processDefinition.getId());
//查询任务实例
List<Task> taskList = taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).list();
Assert.assertNotNull(taskList == null);
Assert.assertTrue(taskList.size() > 0);
for (Task task : taskList) {
System.out.println("task name is " + task.getName() + " ,task key is " + task.getTaskDefinitionKey());
}
}
}<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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"
expressionLanguage="http://www.w3.org/1999/XPath" id="m1478052557696" name=""
targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="myProcess" isClosed="false" isExecutable="true" name="My process" processType="None">
<startEvent id="startevent1" name="Start"/>
<endEvent id="endevent1" name="End"/>
<userTask activiti:exclusive="true" id="usertask1" name="提交申请"/>
<userTask activiti:exclusive="true" id="usertask2" name="主管审批"/>
<userTask activiti:exclusive="true" id="usertask3" name="经理审批"/>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"/>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"/>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"/>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram
documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0"
id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="myProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="Shape-startevent1">
<omgdc:Bounds height="32.0" width="32.0" x="125.0" y="80.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="Shape-endevent1">
<omgdc:Bounds height="32.0" width="32.0" x="515.0" y="320.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="Shape-usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="300.0" y="70.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="Shape-usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="300.0" y="190.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="Shape-usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="480.0" y="190.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1" sourceElement="startevent1"
targetElement="usertask1">
<omgdi:waypoint x="157.0" y="96.0"/>
<omgdi:waypoint x="300.0" y="97.5"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2" sourceElement="usertask1"
targetElement="usertask2">
<omgdi:waypoint x="352.5" y="125.0"/>
<omgdi:waypoint x="352.5" y="190.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3" sourceElement="usertask2"
targetElement="usertask3">
<omgdi:waypoint x="405.0" y="217.5"/>
<omgdi:waypoint x="480.0" y="217.5"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4" sourceElement="usertask3"
targetElement="endevent1">
<omgdi:waypoint x="531.0" y="245.0"/>
<omgdi:waypoint x="531.0" y="320.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>