学习资料:《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实战--第五章--用户与组及部署管理(三)部署流程及资源读取的更多相关文章

  1. 2017.2.28 activiti实战--第五章--用户与组及部署管理(二)部署流程资源

    学习资料:<Activiti实战> 第五章 用户与组及部署管理(二)部署流程资源 内容概览:讲解流程资源的读取与部署. 5.2 部署流程资源 5.2.1 流程资源 流程资源常用的有以下几种 ...

  2. 2017.2.20 activiti实战--第五章--用户与组及部署管理(一)用户与组

    学习资料:<Activiti实战> 第五章 用户与组及部署管理(一)用户与组 内容概览:讲解activiti中内置的一套用户.组的关系,以及如何通过API添加.删除.查询. 5.1 用户与 ...

  3. 2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单

    学习资料:<Activiti实战> 第七章  Spring容器集成应用实例(五)普通表单 第六章中介绍了动态表单.外置表单.这里讲解第三种表单:普通表单. 普通表单的特点: 把表单内容写在 ...

  4. 2017.2.28 activiti实战--第六章--任务表单(二)外置表单

    学习资料:<Activiti实战> 第六章 任务表单(二)外置表单 6.3 外置表单 考虑到动态表单的缺点(见上节),外置表单使用的更多. 外置表单的特点: 页面的原样显示 字段值的自动填 ...

  5. 2017.2.28 activiti实战--第六章--任务表单(一)动态表单

    学习资料:<Activiti实战> 第六章 任务表单(一)动态表单 内容概览:本章要完成一个OA(协同办公系统)的请假流程的设计,从实用的角度,讲解如何将activiti与业务紧密相连. ...

  6. 2017.2.21 activiti实战--第十三章--流量数据查询与跟踪(一)查询接口介绍及运行时数据查询

    学习资料:<Activiti实战> 第十三章 流量数据查询与跟踪 本章讲解运行时与历史数据的查询方法.主要包含三种:标准查询,Native查询,CustomSql查询. 13.1 Quer ...

  7. 2017.2.22 activiti实战--第六章--任务表单

    学习资料:<Activiti实战> 第六章 任务表单 本章将一步步完成一个协同办公系统(OA)的请假流程的设计,讲解如何将Activiti和实际业务联系起来. 首先讲解动态表单与外置表单的 ...

  8. 2017.2.21 activiti实战--第七章--Activiti与spring集成(一)配置文件

    学习资料:<Activiti实战> 第七章 Activiti与容器集成 本章讲解activiti-spring可以做的事情,如何与现有系统集成,包含bean的注入.统一事务管理等. 7.1 ...

  9. 2017.2.20 activiti实战--第二章--搭建Activiti开发环境及简单示例(二)简单示例

    学习资料:<Activiti实战> 第一章 搭建Activiti开发环境及简单示例 2.5 简单流程图及其执行过程 (1)leave.bpmn 后缀名必须是bpmn.安装了activiti ...

随机推荐

  1. 【LeetCode】Search Insert Position(搜索插入位置)

    这道题是LeetCode里的第35道题. 题目描述: 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元 ...

  2. maven国内镜像

    <?xml version="1.0" encoding="UTF-8"?> <!--Licensed to the Apache Softw ...

  3. Linux常用命令与基本概念

    复制 文件的复制 cp 源文件 目标文件 文件夹的复制 cp -r 源文件夹 目标文件夹 删除 删除文件 rm 文件名 删除文件夹 rm -rf 文件夹 查看文件类型 file 文件名 压缩与解压 z ...

  4. POJ 3254:Corn Fields(状态压缩DP)

    题目大意:一个矩形的草地,分为多个格子,有的格子可以有奶牛(标为1),有的格子不可以放置奶牛(标为0),计算摆放奶牛的方案数. 分析: f[i,j]表示第i行状态为j的方案总数. 状态转移方程f[i, ...

  5. BZOJ 1564 :[NOI2009]二叉查找树(树型DP)

    二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ...

  6. [NOI2011][bzoj2434] 阿狸的打字机 [AC自动机+dfs序+fail树+树状数组]

    题面 传送门 正文 最暴力的 最暴力的方法:把所有询问代表的字符串跑一遍kmp然后输出 稍微优化一下:把所有询问保存起来,把模板串相同的合并,求出next然后匹配 但是这两种方法本质没有区别,都是暴力 ...

  7. [POJ1160] Post Office [四边形不等式dp]

    题面: 传送门 思路: dp方程实际上很好想 设$dp\left[i\right]\left[j\right]$表示前$j$个镇子设立$i$个邮局的最小花费 然后状态转移: $dp\left[i\ri ...

  8. 剑指offer42:翻转单词顺序 VS 左旋转字符串(更高效、简便的解法)

    题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a student." ,则输出" ...

  9. 如何在MySQL中导入大容量SQL文件

    在实际工作中,有时需要导入大容量sql文件到MySQL,通常有以下三种方法: (1)通过phpmyadmin,不推荐,有内存等的限制: (2)通过Navicat Premium工具运行sql,不推荐, ...

  10. 洛谷 [P3381] 最小费用最大流模版

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...