
正文
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的使用,及一些重要参数。
部署管理介绍了资源的种类,四种部署方式,如何读取已部署资源。








