2017.2.28 activiti实战--第五章--用户与组及部署管理(三)部署流程及资源读取
学习资料:《Activiti实战》
第五章 用户与组及部署管理(三)部署流程及资源读取
内容概览:如何利用API读取已经部署的资源,比如读取流程定义的XML文件,或流程对应的图片文件。
以下示例均基于SpringMVC。
5.3 部署流程及资源读取
5.3.1 读取已部署的processdefinition
假设现已有了一个页面,用于浏览及管理processDefinition。ID是流程定义id,DID是部署ID,名称是流程定义名称,KEY是流程定义KEY。XML和图片是流程定义的资源文件。
这个页面的访问路径是/chapter5-oa-manager/chapter5/process-list。
对应的jsp文件是webapp/WEB-INF/views/chapter5/process-list.jsp。

(1)process-list.jsp文件
完整代码与重点代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<%@ include file="/common/global.jsp"%>
<%@ include file="/common/meta.jsp" %>
<%@ include file="/common/include-base-styles.jsp" %>
<title>已部署流程定义列表--chapter5</title>
</head>
<body>
<table width="100%" class="table table-bordered table-hover table-condensed">
<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>${pd.resourceName }</td>
<td>${pd.diagramResourceName }</td>
</c:forEach>
</tbody>
</table>
</body>
</html>
process-list.jsp
34 <tbody>
35 <c:forEach items="${processDefinitionList }" var="pd">
36 <tr>
37 <td>${pd.id }</td>
38 <td>${pd.deploymentId }</td>
39 <td>${pd.name }</td>
40 <td>${pd.key }</td>
41 <td>${pd.version }</td>
42 <td>${pd.resourceName }</td>
43 <td>${pd.diagramResourceName }</td>
44 </c:forEach>
45 </tbody>
(2)DeploymentController
完整代码和重点代码如下:
@Controller
@RequestMapping(value = "/chapter5")
public class DeploymentController extends AbstractController { RepositoryService repositoryService = processEngine.getRepositoryService(); /**
* 流程定义列表
*/
@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;
}
}
ModelAndView mav = new ModelAndView("chapter5/process-list");
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
mav.addObject("processDefinitionList", processDefinitionList);
return mav;
5.3.2 从客户端部署流程
上节中可以获取到已经部署的流程,展示在列表里。这一节,通过web界面或其他客户端来部署processDefinition。这里采用上传文件的方式。
(1)process-list.jsp
添加代码如下:
<body>
<fieldset id="deployFieldset">
<legend>部署流程资源</legend>
<span class="alert alert-info"><b>支持文件格式:</b>zip、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" class="btn" />
</form>
<hr class="soften" />
</fieldset>
...
</body>
(2)DeploymentController
添加方法如下:(类的路径是/chapter5,方法的路径是/deploy)
/**
* 部署流程资源
*/
@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";// 回到列表页
}
5.3.3 读取流程定义的XML
现在增加一个功能,为列表中的"XML资源名称"添加一个链接,单击时,可以查看流程定义的XML文件内容。
(1)process-list.jsp
修改列的设置。
<!--原来的代码
<td>${pd.resourceName }</td>
--> <!--修改如下-->
<td>
<a target="_blank" href='${ctx }/chapter5/read-resource?pdid=${pd.id }&resourceName=${pd.resourceName }'>${pd.resourceName }
</a>
</td>
(2)DeploymentController
添加方法如下:(类的路径是/chapter5,方法的路径是/read-resource)
/**
* 读取流程资源
*
* @param processDefinitionId 流程定义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);
}
}
(3)运行效果
点击
,跳转到页面:
localhost:8080/chapter5-oa-manager/chapter5/read-resource?pdid=candidateUserInUserTask:1:4&resourceName=candidateUserInUserTask.bpmn
xml文件的内容被完整显示。

5.3.4 读取流程定义的图片文件
不管是bpmn还是png,对engine来说,都是资源文件。所以这里和前面的读取XML文件,所完成的功能类似。因此,二者在Controller里的方法是共用的。
所以只需修改jsp中的这句话为:注意,图片文件是diagramResource。
<td>
<a target="_blank" href='${ctx }/chapter5/read-resource?pdid=${pd.id }&resourceName=${pd.diagramResourceName }'>${pd.diagramResourceName }
</a>
</td>
5.3.5 读取流程定义图片时出现的中文乱码问题
读取XML文件和图片文件的区别:部署一个processDefinition时,bpmn文件是一定存在的,但是png文件可以没有。此时,engine会进行判定,如果没有部署时读取的资源里不包含png文件,它会自动生成同名文件。
因此会造成两个问题:坐标遗失及中文乱码。
5.3.2中读取xml内容时,显然内容中是没有坐标信息的,即engine帮我们自动生成的图片,布局的位置无法与bpmn中一模一样。同时,activiti默认的字体是Arial,在windows下默认自带宋体。所以转换时,会出现乱码。
(1)坐标遗失
解决办法:部署时,bpmn文件和图片文件打包为zip/bar同时部署。不要让activiti为我们在部署的时候才自动生成。(Eclipse插件activiti designer中进行流程绘制时,可以设置为点击保存bpmn的同时立即生成png图片。在这个插件中绘制,查看bpmn文件的xml内容时 ,可以看到坐标信息。)
(2)中文乱码
乱码解决办法1:
修改类org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas的其中一句代码如下:
//Font font = new Font("Arial",Font.BOLD,11);
Font font = new Font("simsun",Font.BOLD,11);//宋体是simsun
缺点:动了源代码,导致使用activiti的升级版本时,又要做同样修改。
乱码解决办法2:
在processConfiguration的配置中增加这段:
<bean id="processEngineConfiguration" class="...">
<!--修改字体-->
<property name="activityFontName" value="宋体">
<property name="labelFontName" value="宋体">
</bean>
乱码解决办法3:
部署时,bpmn文件和图片文件打包为zip/bar同时部署。不要让activiti为我们在部署的时候才自动生成。
综上可以看到:部署时,bpmn文件和图片文件打包为zip/bar同时部署,可以同时解决这两个问题。其他一些更细微的问题,比如显示不全,也可以解决。所以,最后的结论就是,将bpmn和png一起打包部署吧。
5.3.6 删除部署
(1)process-list.jsp
添加一列,用来执行删除操作。
<td><a target="_blank" href='${ctx }/chapter5/delete-deployment?deploymentId=${pd.deploymentId }'>删除</a></td>
(2)DeploymentController
添加方法如下:(类的路径是/chapter5,方法的路径是/delete-deployment)
/**
* 删除部署的流程,级联删除流程实例
*
* @param deploymentId 流程部署ID
*/
@RequestMapping(value = "/delete-deployment")
public String deleteProcessDefinition(@RequestParam("deploymentId") String deploymentId) {
repositoryService.deleteDeployment(deploymentId, true);//true表示同时把与流程相关的数据也一并删除
return "redirect:process-list";
}
本章小结
介绍了用户与组、部署管理两大块。
用户与组介绍了API的使用,及一些重要参数。
部署管理介绍了资源的种类,四种部署方式,如何读取已部署资源。
2017.2.28 activiti实战--第五章--用户与组及部署管理(三)部署流程及资源读取的更多相关文章
- 2017.2.28 activiti实战--第五章--用户与组及部署管理(二)部署流程资源
学习资料:<Activiti实战> 第五章 用户与组及部署管理(二)部署流程资源 内容概览:讲解流程资源的读取与部署. 5.2 部署流程资源 5.2.1 流程资源 流程资源常用的有以下几种 ...
- 2017.2.20 activiti实战--第五章--用户与组及部署管理(一)用户与组
学习资料:<Activiti实战> 第五章 用户与组及部署管理(一)用户与组 内容概览:讲解activiti中内置的一套用户.组的关系,以及如何通过API添加.删除.查询. 5.1 用户与 ...
- 2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单
学习资料:<Activiti实战> 第七章 Spring容器集成应用实例(五)普通表单 第六章中介绍了动态表单.外置表单.这里讲解第三种表单:普通表单. 普通表单的特点: 把表单内容写在 ...
- 2017.2.28 activiti实战--第六章--任务表单(二)外置表单
学习资料:<Activiti实战> 第六章 任务表单(二)外置表单 6.3 外置表单 考虑到动态表单的缺点(见上节),外置表单使用的更多. 外置表单的特点: 页面的原样显示 字段值的自动填 ...
- 2017.2.28 activiti实战--第六章--任务表单(一)动态表单
学习资料:<Activiti实战> 第六章 任务表单(一)动态表单 内容概览:本章要完成一个OA(协同办公系统)的请假流程的设计,从实用的角度,讲解如何将activiti与业务紧密相连. ...
- 2017.2.21 activiti实战--第十三章--流量数据查询与跟踪(一)查询接口介绍及运行时数据查询
学习资料:<Activiti实战> 第十三章 流量数据查询与跟踪 本章讲解运行时与历史数据的查询方法.主要包含三种:标准查询,Native查询,CustomSql查询. 13.1 Quer ...
- 2017.2.22 activiti实战--第六章--任务表单
学习资料:<Activiti实战> 第六章 任务表单 本章将一步步完成一个协同办公系统(OA)的请假流程的设计,讲解如何将Activiti和实际业务联系起来. 首先讲解动态表单与外置表单的 ...
- 2017.2.21 activiti实战--第七章--Activiti与spring集成(一)配置文件
学习资料:<Activiti实战> 第七章 Activiti与容器集成 本章讲解activiti-spring可以做的事情,如何与现有系统集成,包含bean的注入.统一事务管理等. 7.1 ...
- 2017.2.20 activiti实战--第二章--搭建Activiti开发环境及简单示例(二)简单示例
学习资料:<Activiti实战> 第一章 搭建Activiti开发环境及简单示例 2.5 简单流程图及其执行过程 (1)leave.bpmn 后缀名必须是bpmn.安装了activiti ...
随机推荐
- python实现算法: 多边形游戏 数塔问题 0-1背包问题 快速排序
去年的算法课挂了,本学期要重考,最近要在这方面下点功夫啦! 1.多边形游戏-动态规划 问题描述: 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值, 每条边被 ...
- manjaro安装anaconda出错
出错信息: ==> Creating package "anaconda"... -> Generating .PKGINFO file... -> Gene ...
- gcc学习记录
-Wall: 使输出中包含警告信息,提示一些可以避免的错误.如果没有错误,则不会输出信息. -o:后面加上可执行文件的名字.如果不加-o选项,会默认生成a.out可执行文件.举例:gcc -Wall ...
- DFS和BFS遍历的问题
来自https://github.com/soulmachine/leetcode 广度优先搜索 输入数据:没有什么特征,不像dfs需要有递归的性质.如果是树/图,概率更大. 状态转换图:数或者DAG ...
- java如何建项目
java常开发的项目有哪几种? 这几种项目都是怎么建的?
- 【bzoj4448】[Scoi2015]情报传递 主席树
题目描述 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈特公司纪律森严, ...
- ZigBee学习五 无线温度检测
ZigBee学习五 无线温度检测 1)修改公用头文件GenericApp.h typedef union h{ uint8 TEMP[4]; struct RFRXBUF { unsigned cha ...
- HDU 2065 "红色病毒"问题 ——快速幂 生成函数
$A(x)=1+x^2/2!+x^4/4!...$ $A(x)=1+x^1/1!+x^2/2!...$ 然后把生成函数弄出来. 暴力手算. 发现结论. 直接是$4^{n-1}+2^{n-1}$ 然后快 ...
- 计数(count)
计数(count) 题目描述 既然是萌萌哒 visit_world 的比赛,那必然会有一道计数题啦! 考虑一个 NN个节点的二叉树,它的节点被标上了 1∼N1∼N 的编号. 并且,编号为 ii的节点在 ...
- Codeforces Beta Round #95 (Div. 2) C 组合数学
C. The World is a Theatre time limit per test 2 seconds memory limit per test 256 megabytes input st ...