学习资料:《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. Linux下c++使用pthread库

    pthread 库是纯c库,没有类指针的概念,当想phread_create中传递类成员函数时,就会报错,这里针对这种情况,对线程创建做了必要封装,较为简单,继承类,实现run接口,然后使用start ...

  2. 关于ContextImp的源码分析

      关于ContextImp的源码分析 来源: http://blog.csdn.net/qinjuning/article/details/7310620 Context概述:   Android ...

  3. Manthan, Codefest 16 B 数学

    B. A Trivial Problem time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  4. codeforce div2 426 D. The Bakery

    D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  5. javascript实现htmlEncode与htmlDecode

    原文发布时间为:2011-04-19 -- 来源于本人的百度文章 [由搬家工具导入] htmlencode with javascript function htmlEncode(html) {    ...

  6. 改变querystring值,然后重定向

    原文发布时间为:2009-11-13 -- 来源于本人的百度文章 [由搬家工具导入] 本页面改变querystring值,然后重定向 本页面,避免出现重复querystring。。 如避免出现 www ...

  7. js禁用"Backspace"键(即禁止网页倒退)

    项目遇到的一个问题一个普通网页,如果这个网页上没有焦点的话,那么点击"Backspace"键的时候,网页会回退(倒退到上一个网页),这样就会就有一个问题,当我在一个输入框进行输入的 ...

  8. GMM 的EM 实现

    算法逻辑在这里: http://www.cnblogs.com/Azhu/p/4131733.html 贴之前先说下,本来呢是打算自己写一个的,在matlab 上,不过,实在是写不出来那么高效和健壮的 ...

  9. bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基

    题目链接 题意 给定一个 \(n(n\le 50000)\) 个点 \(m(m\le 100000)\) 条边的无向图,每条边上有一个权值.请你求一条从 \(1\)到\(n\)的路径,使得路径上的边的 ...

  10. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---35

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: