Liferay7 BPM门户开发之44: 集成Activiti展示流程列表
处理依赖关系
集成Activiti之前,必须搞清楚其中的依赖关系,才能在Gradle里进行配置.
依赖关系:
例如,其中activiti-engine依赖于activiti-bpmn-converter,而activiti-bpmn-converter又依赖于activiti-bpmn-model
那么这以下的引用都是要设置的,缺一不可,否则portlet会无法注入进OSGi容器
org.activiti:activiti-engine:jar:5.xx.0
+- org.activiti:activiti-bpmn-converter:jar:5.xx.0:compile
| \- org.activiti:activiti-bpmn-model:jar:5.xx.0:compile
| +- com.fasterxml.jackson.core:jackson-core:jar:2.2.3:compile
| \- com.fasterxml.jackson.core:jackson-databind:jar:2.2.3:compile
| \- com.fasterxml.jackson.core:jackson-annotations:jar:2.2.3:compile
+- org.activiti:activiti-process-validation:jar:5.xx.0:compile
+- org.activiti:activiti-image-generator:jar:5.xx.0:compile
+- org.apache.commons:commons-email:jar:1.2:compile
| +- javax.mail:mail:jar:1.4.1:compile
| \- javax.activation:activation:jar:1.1:compile
+- org.apache.commons:commons-lang3:jar:3.3.2:compile
+- org.mybatis:mybatis:jar:3.2.5:compile
+- org.springframework:spring-beans:jar:4.0.6.RELEASE:compile
| \- org.springframework:spring-core:jar:4.0.6.RELEASE:compile
+- joda-time:joda-time:jar:2.6:compile
+- org.slf4j:slf4j-api:jar:1.7.6:compile
+- org.slf4j:jcl-over-slf4j:jar:1.7.6:compile
接下来,需要完成Gradle的设置,
全部:
dependencies {
compile 'com.liferay.portal:com.liferay.portal.kernel:2.0.0'
compile 'com.liferay.portal:com.liferay.util.bridges:2.0.0'
compile 'com.liferay.portal:com.liferay.util.taglib:2.0.0'
compile 'com.liferay:com.liferay.application.list.api:1.0.0'
compile 'javax.portlet:portlet-api:2.0'
compile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'org.osgi:org.osgi.service.component.annotations:1.3.0'
compile 'org.osgi:org.osgi.compendium:5.0.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.2.3'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.2.3'
compileOnly group: "jstl", name: "jstl", version: "1.2"
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.6'
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.6'
compile group: 'commons-logging', name: 'commons-logging', version: '1.2'
compile group: 'org.joda', name: 'joda-convert', version: '1.2'
compile group: 'joda-time', name: 'joda-time', version: '2.6'
compile group: 'org.apache.commons', name: 'commons-email', version: '1.4'
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.2'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
compile group: 'org.mybatis', name: 'mybatis', version: '3.3.0'
compile group: 'org.springframework', name: 'spring-core', version: '4.1.5.RELEASE'
compile group: 'org.springframework', name: 'spring-beans', version: '4.1.5.RELEASE'
compile 'org.springframework:spring-webmvc:4.1.5.RELEASE'
compile 'org.springframework:spring-webmvc-portlet:4.1.5.RELEASE'
compile group: 'org.activiti', name: 'activiti-bpmn-model', version: '5.21.0'
compile group: 'org.activiti', name: 'activiti-bpmn-converter', version: '5.21.0'
compile group: 'org.activiti', name: 'activiti-engine', version: '5.21.0'
testCompile 'junit:junit:4.+'
}
Portlet java
ProcessListPortlet:
package com.lifiti.portlet; import java.io.IOException;
import java.util.List;
import javax.portlet.Portlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.activiti.engine.repository.ProcessDefinition;
import org.osgi.service.component.annotations.Component; import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.util.ParamUtil; @Component(immediate = true,
property = { "com.liferay.portlet.display-category=category.sample",
"com.liferay.portlet.instanceable=true",
"javax.portlet.display-name=Process List",
"javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/process/processList.jsp",
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=power-user,user" },
service = Portlet.class)
public class ProcessListPortlet extends BpmBasePortlet { @Override
public void render(RenderRequest request, RenderResponse response) throws PortletException, IOException { List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
request.setAttribute("processDefinitionList", processDefinitionList);
super.render(request, response);
}
}
jsp页面
<%@ include file="/init.jsp" %> <portlet:renderURL var="render">
<portlet:param name="mvcRenderCommandName" value="/porcess/bpmn" />
</portlet:renderURL> <table width="100%" class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th><liferay-ui:message key="ProcessDef"/></th>
<th><liferay-ui:message key="DeplyID"/></th>
<th><liferay-ui:message key="ProcessName"/></th>
<th><liferay-ui:message key="ProcessDefKey"/></th>
<th><liferay-ui:message key="Version"/></th>
<th>BPMN</th>
<th><liferay-ui:message key="ImageResource"/></th>
<th width="80"><liferay-ui:message key="Operation"/></th>
<th width="80"><liferay-ui:message key="Start"/></th>
</tr>
</thead>
<tbody>
<c:forEach items="${processDefinitionList }" var="pd">
<portlet:actionURL var="viewURL" name="imageAction">
<portlet:param name="mvcRenderCommandName" value="/process/viewResource" />
<portlet:param name="pdid" value="${pd.id }" />
<portlet:param name="diagramResourceName" value="${pd.diagramResourceName }" />
</portlet:actionURL>
<portlet:renderURL var="viewXML">
<portlet:param name="mvcRenderCommandName" value="/porcess/bpmn" />
<portlet:param name="pdid" value="${pd.id }" />
<portlet:param name="resourceName" value="${pd.resourceName }" />
</portlet:renderURL>
<tr>
<td>${pd.id }</td>
<td>${pd.deploymentId }</td>
<td>${pd.name }</td>
<td>${pd.key }</td>
<td>${pd.version }</td>
<td><aui:button href="<%= viewXML %>" value="View XML" /></td>
<td><aui:button href="<%= viewURL %>" value="${pd.diagramResourceName eq null?'-':'png' }"/> </td>
</tr>
</c:forEach>
</tbody>
</table>
需要注意的是,还需要把jar文件放置在osgi的modules目录下,非常重要

查看BPMN描述文件
jsp 定义,其中mvcRenderCommandName定义了Action的URL地址,在MVCRenderCommand类中将会对应
<%@ include file="/init.jsp" %>
<aui:input name="xml" type="textarea" label ="XML:" value="${bpmnOutput}"></aui:input>
MVCRenderCommand 链接处理JAVA类
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCRenderCommand;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.osgi.service.component.annotations.Component; @Component(
immediate = true,
property = {
"javax.portlet.name=com_lifiti_portlet_ProcessListPortlet",
"mvc.command.name=/respository/viewBPMN"
},
service = MVCRenderCommand.class
)
public class BladeMVCRenderCommand implements MVCRenderCommand { @Override
public String render(
RenderRequest renderRequest, RenderResponse renderResponse)
throws PortletException { ...
//处理逻辑 Here
...
return "/process/viewBPMN.jsp";
} }
一些通用类
将来会把它们独立出一个工程,暂时先放在一个工程里
BPM Portlet基类
package com.lifiti.portlet; import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.lifiti.util.ActivitiUtils; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream; import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService; public class BpmBasePortlet extends MVCPortlet{ protected Log _log = LogFactoryUtil.getLog(getClass()); protected ProcessEngine processEngine = null;
protected RepositoryService repositoryService;
protected RuntimeService runtimeService;
protected TaskService taskService;
protected HistoryService historyService;
protected IdentityService identityService;
protected ManagementService managementService;
protected FormService formService; public BpmBasePortlet() {
super();
processEngine = ActivitiUtils.getProcessEngine();
repositoryService = processEngine.getRepositoryService();
runtimeService = processEngine.getRuntimeService();
taskService = processEngine.getTaskService();
historyService = processEngine.getHistoryService();
identityService = processEngine.getIdentityService();
managementService = processEngine.getManagementService();
formService = processEngine.getFormService();
} public ByteArrayOutputStream inputStream2ByteArrayOutputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos;
} }
Activiti通用日志事件记录(监听器):
public class BpmJobEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
switch (event.getType()) {
case JOB_EXECUTION_SUCCESS:
_log.info("A job done!");
......
break;
case JOB_EXECUTION_FAILURE:
_log.error("A job has failed...");
break;
default:
_log.info("Event received: " + event.getType());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
全部的监听类型清单:
http://activiti.org/userguide/index.html#eventDispatcherEventTypes
通过RuntimeService来注册和删除监听器
注册监听:
void addEventListener(ActivitiEventListener listenerToAdd);
void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types);
删除监听:
void removeEventListener(ActivitiEventListener listenerToRemove);
这样一个Portlet就开发出来了,感觉靠拖拽放在页面,再设置访问权限有些繁琐,我们还想把它直接放进控制面板里。
界面:

XML模板察看

点击PNG按钮,查看流程图,我尝试用InputStream把图片资源以流的形式输出到ServletResponse的OutStream流,结果失败,还尝试另存为PNG,输出有乱码。
于是想了2个替代解决方案
1、写一个独立的Activiti的rest服务,用来独立输出PNG;
2、利用Activiti自带的rest服务
用第一方式的实现,端口为8070,注意需要注入2个url参数,分别是pdid和resourceName

用Activiti自带的rest服务,端口8082
URL例如http://localhost:8082/activiti-rest/service/repository/deployments/262561/resources
其中262561就是流程部署ID,即deploymentId

本篇结束。
Activiti的集成开发系列文章集合在这里:
http://www.cnblogs.com/starcrm/p/6047486.html
方便索引。
SourceCode Download:
全部工程源代码下载
http://download.csdn.net/detail/starcrm/9712664
Liferay7 BPM门户开发之44: 集成Activiti展示流程列表的更多相关文章
- Liferay7 BPM门户开发之26: 集成Activiti到Liferay7
开发顺序: 实战任务1,开发BPM管理后台(用于在Liferay管理中心管理Activiti模型上传) 一个熟悉Portlet操作的项目,为开发打好基础. http://www.cnblogs.com ...
- Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步
在实际的BPM集成开发过程中,Liferay和Activiti这两个异构的系统之间,用户.组的同步需求非常重要,用来实现签收组的概念,比如指定签收组.会签.抢签都需要用到. Activiti可以通过自 ...
- Liferay7 BPM门户开发之45: 集成Activiti文件上传部署流程BPMN模型
开发文件上传,部署流程模板. 首先,开发jsp页面,deploy.jsp <%@ include file="/init.jsp" %> <h3>${RET ...
- Liferay7 BPM门户开发之47: 集成Activiti待办已办任务清单和流程启动
首先增加两个Portlet,分别用于待办处理.流程启动.待办是别人发起的流程,流到自己这里的流程:流程启动用于发起新的流程. 程序文件放置于 在ACtivit中待办概念分两种,1是指派给你的,专门的指 ...
- Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发
hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...
- Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)
开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...
- Liferay7 BPM门户开发之17: Portlet 生命周期
Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() ...
- Liferay7 BPM门户开发之12:acitiviti和liferay用户权限体系集成
写到第12章才出现Liferay的内容,希望可以厚积薄发. 我们的目标是不使用不维护Activiti的用户组织架构,只维护Liferay的体系,这样的好处是非常明显的,即不用做组织架构的同步工作. 原 ...
- Liferay7 BPM门户开发之7: Activiti中的重要概念和主要数据库结构
流程的人员参与角色: Assignee :签收者(即待办人) Candidate:候选人 Owner:拥有者 Starter:启动者 participant:参与者,包含查阅 流程变量的类型: Str ...
随机推荐
- js生成验证码并检验
<html> <head> <title>验证码</title> <style type="text/css"> #co ...
- Python 学习---------Day4
第十章 Python语句简介Python的代码书写要求,以及换行等语句可以扩越多行,只要将其封闭在圆括号内,方括号内或大括号内即可,可以使用分号终止.用\可以允许我们跨越多行一个简单的交互式循环whi ...
- protobuf坑1
或者说特性吧,没仔细看protobuf代码,也许我还理解不够. 按照陈硕大牛的这篇帖子的介绍,“它包含了程序编译的时候所链接的全部 protobuf Message types” 实际开发过程中发现必 ...
- iOS进阶_三方使用步骤
一.配置环境(:后为在终端输入的命令) 打开终端 查看自己电脑的Ruby环境:gem sources -l 如果环境已经是淘宝镜像了,此时不需要再进行环境的修改. 如果不是,发送gem sources ...
- 结对开发训练(郭林林&胡潇丹)
此次编程题为:求一个整数数组最大子数组之和,要求时间复杂度为O(n). 首先,我们对题目做出分析,做出第一种预行方案,即定义一个数组,当数组中元素大于等于0时,进行累加:若小于0,则与后面的数作比较, ...
- [置顶]PADS PCB功能使用技巧系列之NO.002- 如何走差分线?
差分信号在高速电路设计中应用越来越广泛,如USB.HDMI.PCI.DDR*等,承载差分信号的差分线主要优势有:抗干扰能力强,能有效抑制EMI.时序定位精确等,对于PCB工程师来说,最关注的是如何确保 ...
- MVVM框架中的一个非常重要的内容:数据双向绑定
双向绑定的意思就是,如下图中,当在input框中输入字符时,红色框框中的字也会随之改变. input框中需要一个绑定:ms-duplex(即“双工绑定”),http://avalonjs.github ...
- Zookeeper初次使用
下面介绍Linux系统中Zookeeper的初次使用方法. 1.jdk安装和zookeeper下载 首先从jdk官网中下载jdk文件,然后将文件放在/usr/local/java目录下解压,并打开.b ...
- Linux(centeros)下安装jdk
首先需要说明的是有的Linux系统自带jdk,这个jdk是openjdk,可以通过java-version查看 所以安装的步骤是,首先删除系统自带的(如果有)openjdk 1. rpm -qa | ...
- linux-11 基本命令之 -工作期目录切换命令-pwd,cd,
pwd 命令用于显示当前的工作目录,格式为:pwd[选项] @1.查看当前的工作路径: [root@localhost /]# pwd cd 命令用于切换工作路径 格式为:"cd 目录名称& ...