zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Source InSight context 窗口丢失的解决办法
    [EffectiveC++]item41:了解隐式接口和编译器多态
    [EffectiveC++]item04:Make sure the objects are initialized before they're used
    [EffectiveC++]item3:尽可能使用const
    linux man指令问题
    解读ARM成功秘诀:薄利多销推广产品
    source insight设置问题 [问题点数:20分,结帖人leecapacity]
    totalcommander
    firefox
    处理SecureCRT中使用vim出现中文乱码问题
  • 原文地址:https://www.cnblogs.com/starcrm/p/6177844.html
Copyright © 2011-2022 走看看