例子来自《activiti实战》
程序文件结构
1.pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wei.activiti</groupId>
<artifactId>ActivitiTest-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- 属性配置以及各个依赖的版本 -->
<properties>
<!-- 各个依赖的版本号 -->
<activiti.version>5.16.4</activiti.version>
<spring.version>4.0.6.RELEASE</spring.version>
<jetty.version>8.1.11.v20130520</jetty.version>
<commons-lang3.version>3.1</commons-lang3.version>
<commons-io.version>2.4</commons-io.version>
<slf4j.version>1.7.2</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<hibernate.version>4.1.4.Final</hibernate.version>
<cxf.version>2.6.14</cxf.version>
<drools.version>5.5.0.Final</drools.version>
<mule.version>3.4.0</mule.version>
<!-- 设置编码为UTF-8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- activit begin -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- activit end -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.172</version>
</dependency>
<!-- WEB begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- WEB end-->
<!-- Jackson JSON Mapper -->
<!-- SpringMVC的@ResponseBody需要使用 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- utils -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<!-- 设置项目中依赖jar版本为1.7 Start -->
<finalName>spring-mvc-project</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
<!-- 设置项目中依赖jar版本为1.7 End -->
</build>
</project>
2.配置文件
2.1web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>ActivitiTest-1</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
</param-value>
</context-param>
<!-- Spring的ApplicationContext载入 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Filter定义 -->
<!-- Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring MVC Servlet -->
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>600</session-timeout>
</session-config>
</web-app>
2.2spring-mvc.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"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.wei.activiti" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<!-- 定义首页 -->
<mvc:view-controller path="/" view-name="redirect:/login/" />
<!-- 定义JSP -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
p:messageConverters-ref="messageConverters"></bean>
<util:list id="messageConverters">
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter" />
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</util:list>
<!-- 支持上传文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
</beans>
2.3 applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd"
default-lazy-init="true">
<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
<context:component-scan base-package="com.wei.activiti">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>
2.4 activiti.cfg.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="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
3.process-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>已部署流程定义列表</title>
</head>
<body>
<fieldset id="deployFiledset">
<legend>部署流程资源</legend>
<span><b>文件支持格式:</b>ip、bar、bpmn、bpmn20.xml</span>
<form action="${ctx }/chapter5/deploy" method="post" enctype="multipart/form-data" style="margin-top:1em;">
<input type="file" name="file" />
<input type="submit" value="Submit">
</form>
</fieldset>
<hr />
<table>
<thead>
<tr>
<th>流程定义ID</th>
<th>部署ID</th>
<th>流程定义名称</th>
<th>流程定义KEY</th>
<th>版本号</th>
<th>XML资源名称</th>
<th>图片资源名称</th>
<th width="80">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${processDefinitionList }" var="pd">
<tr>
<td>${pd.id }</td>
<td>${pd.deploymentId }</td>
<td>${pd.name }</td>
<td>${pd.key }</td>
<td>${pd.version }</td>
<td><a target="_blank" href='${ctx }/chapter5/read-resource?pdid=${pd.id }&resourceName=${pd.resourceName }'>${pd.resourceName }</a></td>
<td><a target="_blank" href='${ctx }/chapter5/read-resource?pdid=${pd.id }&resourceName=${pd.diagramResourceName }'>${pd.diagramResourceName }</a></td>
<td><a target="_blank" href='${ctx }/chapter5/delete-deployment?deploymentId=${pd.deploymentId }'>删除</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
4.DeploymentController.java
package com.wei.activiti;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;
import javax.servlet.http.HttpServletResponse;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
/**
* 部署流程
* @author Administrator
*
*/
@Controller
@RequestMapping(value = "/chapter5")
public class DeploymentController extends AbstractController{
RepositoryService repositoryService = pe.getRepositoryService();
/**
* 获取流程定义列表,返回已定义的流程信息
* @return ModelAndView
*/
@RequestMapping(value="/process-list")
public ModelAndView processList(){
//对应WEB-INF/views/chapter5/process-list.jsp
ModelAndView mav = new ModelAndView("chapter5/process-list");
List<ProcessDefinition> processDefinitionList =
repositoryService.createProcessDefinitionQuery().list();
mav.addObject("processDefinitionList",processDefinitionList);
return mav;
}
/**
* 部署流程资源
*/
@RequestMapping(value="/deploy")
public String deploy(@RequestParam(value="file",required=true) MultipartFile file ){
//获取上传的文件名
String filename = file.getOriginalFilename();
try{
//得到输入流(字节流)对象
InputStream fileInputStream = file.getInputStream();
//文件的扩展名
String extension = FilenameUtils.getExtension(filename);
//zip或者bar类型的文件用ZipInputStream方式部署
DeploymentBuilder deployment = repositoryService.createDeployment();
if(extension.equals("zip")||extension.equals("bar")){
ZipInputStream zip = new ZipInputStream(fileInputStream);
deployment.addZipInputStream(zip);
}else{
//其他类型的文件直接部署
deployment.addInputStream(filename, fileInputStream);
}
deployment.deploy();
}catch(Exception e){
logger.error("error on deploy process,because of file input stream");
}
return "redirect:process-list";
}
/**
* 读取流程资源
*
* @param processDefintionId 流程定义ID
* @param resourceName 资源名称
*/
@RequestMapping(value="/read-resource")
public void readResource(@RequestParam("pdid") String processDefinitionId,@RequestParam("resourceName") String resourceName,HttpServletResponse response)
throws Exception
{
ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
ProcessDefinition pd = pdq.processDefinitionId(processDefinitionId).singleResult();
//通过接口读取
InputStream resourceAsStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
//输出资源内容到相应对象
byte[] b = new byte[1024];
int len = -1;
while((len=resourceAsStream.read(b,0,1024))!=-1){
response.getOutputStream().write(b, 0, len);
}
}
/**
* 删除部署的流程,级联删除流程实例
* @param deploymentId 流程部署ID
*/
@RequestMapping(value="/delete-deployment")
public String deleteProcessDefinition(@RequestParam("deploymentId") String deploymentId){
repositoryService.deleteDeployment(deploymentId,true);
return "redirect:process-list";
}
}
5.AbstractController.java
package com.wei.activiti;
import org.activiti.engine.ProcessEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.ActivitiUtils;
public abstract class AbstractController {
protected Logger logger = LoggerFactory.getLogger(getClass());
protected ProcessEngine pe = null;
public AbstractController(){
super();
pe = ActivitiUtils.getProcessEngine();
}
}
6.ActiviyiUtils.java
package util;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
/**
* Activiti工具类,只有一个方法,获得单例的ProcessEngine对象
* @author Administrator
*
*/
public class ActivitiUtils {
private static ProcessEngine pe;
/**
* 单例模式获取引擎对象
*/
public static ProcessEngine getProcessEngine(){
if(pe==null){
/**
* 使用默认的配置文件名称(activiti.cfg.xml)创建引擎对象
*/
pe = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault().buildProcessEngine();
}
return pe;
}
}