由于工作需要,新接到一个小项目,什么?项目,ofbiz走起!项目中需要用到两个小流程,什么?流程 activiti5走起~
activiti5 是原生支持spring 的,可是怎么能让它与ofbiz整合到一块呢,ofbiz确实有自己的sharp 啥的,可是弄不懂啊,资料太少了。可是ofbiz与activiti5整合的资料更少啊,没办法,面对activii5的流程编辑器的诱惑,自己想招吧!
其实整合起来并不复杂,代码量也不多,我就来一步一步说具体操作
1.下载activiti5,我是从官网下的最新版 下载下来解压,我了个去这么些jar ,其实用到的也不多,主要用的有
activiti-bpmn-converter-5.17.0.jar
activiti-bpmn-layout-5.17.0.jar
activiti-bpmn-model-5.17.0.jar
activiti-common-rest-5.17.0.jar
activiti-crystalball-5.17.0.jar
activiti-diagram-rest-5.17.0.jar
activiti-engine-5.17.0.jar
activiti-explorer-5.17.0.jar
activiti-image-generator-5.17.0.jar
activiti-json-converter-5.17.0.jar
activiti-modeler-5.17.0.jar
activiti-process-validation-5.17.0.jar
activiti-simple-workflow-5.17.0.jar
commons-lang3-3.3.2.jar
jackson-annotations-2.2.3.jar
jackson-core-2.2.3.jar
jackson-databind-2.2.3.jar
javaGeom-0.11.1.jar
joda-time-2.6.jar
mybatis-3.2.5.jar
2.我使用的是ofbiz13就是最新版本那个,下一步就是新建一个component 叫做workflow模块
我是建在了framework 下面的,架构级么哈哈,新建component 我就不多介绍了,很多资料可以参考,我新建的component 包含了一下内容:
3 导入jar 包 并且添加classpath中(也就是说在ofbiz-component.xml中包含workflow的lib文件夹),如果component创建的配置都对的话,把你新建的component 加入到component-loader中,启动一下不报错说明你添加jar包成功了。
4.我的整合思路是通过ofbiz 启动加载 acitiviti 的processEngine 并且提供一个processEngineFactory 来获取activiti 的主要接口,那么在我们业务中随时都可以调用工作流引擎了.所以第一步要正确的加载ProcessEngine
ofbiz 强大之处就体现出来了,可以使用它的container 来加载我们的processEngine,我们创建一个workflowcontainer,并实现ofbiz 的container 接口:
package com.ly.workflow; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.ofbiz.base.container.Container; import org.ofbiz.base.container.ContainerException; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilProperties; import java.util.Properties; /** * Created by bo on 15/4/14. */ public class WorkflowContainer implements Container { private String name; private String dbFile= "workflow.db.properties"; @Override public void init(String[] args, String name, String configFile) throws ContainerException { this.name = name; Debug.log("---启动工作流模块---"); //获取工作流数据库配置文件 Properties jdbc=UtilProperties.getProperties(dbFile); //配置工作流引擎 ProcessEngineConfiguration pecfg = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); pecfg.setJdbcUsername(jdbc.getProperty("username")); pecfg.setJdbcPassword(jdbc.getProperty("password")); pecfg.setJdbcUrl(jdbc.getProperty("url")); pecfg.setJdbcDriver(jdbc.getProperty("driver")); //连接池设置 pecfg.setJdbcMaxActiveConnections(Integer.valueOf(jdbc.getProperty("jdbcMaxActiveConnections"))); pecfg.setJdbcMaxIdleConnections(Integer.valueOf(jdbc.getProperty("jdbcMaxIdleConnections"))); pecfg.setJdbcMaxCheckoutTime(Integer.valueOf(jdbc.getProperty("jdbcMaxCheckoutTime"))); pecfg.setJdbcMaxWaitTime(Integer.valueOf(jdbc.getProperty("jdbcMaxWaitTime"))); //设置启动检查数据表 pecfg.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //创建表并获取流程引擎 ProcessEngine pe = pecfg.buildProcessEngine(); //todo 加载初始化流程 //初始化工作流引擎工厂 WorkflowProcessEngineFactory.init(pe,"default"); Debug.log("---工作流引擎加载成功---"); } @Override public boolean start() throws ContainerException { Debug.log("workflow-start"); return false; } @Override public void stop() throws ContainerException { Debug.log("workflow-stop"); } @Override public String getName() { return null; } }
这里需要注意的是我们要写一个配置文件来配置工作流引擎的数据库, activiti 是有自己的一套数据库框架的,也不是他的就是ibatis。。我们就创建一个配置文件来保存工作流引擎的数据库配置,其实也可以用ofbiz自己的连接池的,如果你需要可以自己配置,我是想把ofbiz本身的业务和工作流分开放不同的数据里。
之后我们就新建一个工厂类来保存我们创建的 processEngine:
package com.ly.workflow; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.RepositoryService; import org.activiti.workflow.simple.converter.WorkflowDefinitionConversionFactory; import org.activiti.workflow.simple.converter.json.SimpleWorkflowJsonConverter; import org.ofbiz.base.lang.Factory; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilObject; import org.ofbiz.entity.Delegator; import java.util.concurrent.ConcurrentHashMap; /** * Created by bo on 15/4/14. */ public abstract class WorkflowProcessEngineFactory implements Factory<ProcessEngine,String> { public static final String module = WorkflowProcessEngineFactory.class.getName(); private static ProcessEngineConfiguration pecfg = null; private static final ConcurrentHashMap<String, ProcessEngine> processEngineCache = new ConcurrentHashMap<String, ProcessEngine>(); public static ProcessEngine getProcessEngine(String processEngineName){ if (processEngineName == null) { processEngineName = "default"; } ProcessEngine processEngine = processEngineCache.get(processEngineName); if (processEngine == null) { Debug.logInfo("没有找到工作流引擎", module); } return processEngine; } public static ProcessEngine getProcessEngine(){ return getProcessEngine("default"); } public static RepositoryService getRepositoryService(String processEngineName){ return getProcessEngine(processEngineName).getRepositoryService(); } public static RepositoryService getRepositoryService(){ return getRepositoryService("default"); } public static void init(ProcessEngine pe,String name){ WorkflowProcessEngineFactory.processEngineCache.put(name,pe); } }
如果你有对acitiviti 的借口需求的话,可以在工厂类中添加不同的获取方法,静态方法么,那块你想用取一下就行了,当然你也可以把processEngine 放到Context 里面方便获取。
4.之后你就可以把container 放在ofbiz 启动配置里面了,我觉得ofbiz的container 就相当于spring 一样,都是容器么,但是我觉得spring把简单的东西复杂化了,用的这个费劲,ofbiz 这点要强不少哦。
启动配置的位置在framework/base/config/ofbiz-containers.xml 中,添加一条你的工作流container:
<container name="workflow-container" loaders="main" class="com.ly.workflow.WorkflowContainer"/>
这样的话你启动ofbiz 就会帮你检查是否有activiti 的数据库和表,没有的话会帮你创建出来
如果没抱错,你现在的工作流引擎就可以使用了。。。
5.当然了,光有这些远远不够,activiti 的modeler 流程编辑器才是重点,它可以让你在线定义流程,图形化,可拖动,用户不就是喜欢这种傻瓜式的么,那么我们也吧流程编辑器也整合过来
其实acitiviti 的流程编辑器就是一大堆html 和js 啥的,通过ajax 请求与后台通讯,我们可以用ofbiz自己些逻辑,而前台交给他的编辑器,首先把activiti 的流程编辑器加进来,解压下载的activiti中 的activiti-explorer.war
编辑器其实就是上图的editor-app文件夹,把它拷贝到framwork/images/web-app/images下面
之后我们需要写一个screen 用来包含编辑器需要的js css 啥的,还有要给编辑器一个流程定义ID,
其实这个页面acitivity 中也有,就是上面那个modeler.html,那简单了拷~~~
新建 一个controller
<request-map uri="ProcessDefineModeler"> <security https="true" auth="true"/> <response name="success" type="view" value="ProcessDefineModeler"/> </request-map>
放在你能访问的WEB-INF/controller.xml中
之后建一个screen 来显示我们要的编辑器
<view-map name="ProcessDefineModeler" type="screen" page="component://workflow/widget/CommonScreens.xml#ProcessDefineModeler"/>
<screen name="ProcessDefineModeler"> <section> <actions> <set field="titleProperty" value="cache"/> <set field="headerItem" value="define"/> <set field="tabButtonItem" value="ProcessDefineEditor"/> </actions> <widgets> <platform-specific> <html> <html-template location="component://workflow/templates/processDefine/ProcessDefineModeler.ftl"/> </html> </platform-specific> </widgets> </section> </screen>
把ftl 创建出来,然后把modeler.html的内容拷贝进去(注意要把引用的js 还有css 还有 angelar js 的东西改成images/editor-app路径,确保里面的文件都能通过你的ofbiz服务器找到)
<div id="main" class="wrapper full clearfix" ng-style="{height: window.height + 'px'}" ng-app="activitiModeler" ng-include="'<@ofbizContentUrl>/images/editor-app/editor.html</@ofbizContentUrl>'"> </div>
主要是个,这个其实才是真正的编辑器。。这里可能要改的东西比较多,慢慢来吧,改到你看到的页面没有错误位置, 还有就是这里要有一个必要参数传进来,就是你的流程定义ID,修改引用路径使用ofbizcontenturl
like this:
<script src="<@ofbizContentUrl>/images/editor-app/libs/es5-shim-15.3.4.5/es5-shim.js</@ofbizContentUrl>"></script>
这里做完之后我们需要一个已有流程定义ID 来进入这个页面,这样才不会抱错,所以我们先来做一个流程管理页面
用semantic ui 加上w2ui 做了一个哈。左侧读出流程定义列表,右边显示流程具体信息和对流程定义的操作
这里的一些东西可以参考 activiti 自带的explore,其实说白了就是把他的explore 给弄成ofbiz版本的了,我的方法比较笨吧。。。但是集成度比较高
让编辑流程按钮 导向我们 流程定义页面跳转
哈哈流程定义图出来了,都是应文的,现在还没空翻译它讲究看吧
现在其实你们显示的还是一堆错误,是因为流程编辑器显示出来需要我们后台提供几个服务接口的,都是ajax json 调用,我们可以用ofbiz 来写后台返回个json 数据给他
修改 editor-app/config.js 把它请求服务的路径改为我们自己的
KISBPM.URL = { getModel: function(modelId) { return ACTIVITI.CONFIG.contextRoot + '/GetProcessModelById?modelId=' + modelId; }, getStencilSet: function() { //return ACTIVITI.CONFIG.contextRoot + '/editor/stencilset?version=' + Date.now(); return '/images/editor-app/stencilset.json'; }, putModel: function(modelId) { return ACTIVITI.CONFIG.contextRoot + '/SaveProcessModelById?modelId=' + modelId+"&" ; } };
还有app-cfg,js
'use strict'; var ACTIVITI = ACTIVITI || {}; ACTIVITI.CONFIG = { 'contextRoot' : '/workflow/control' };
你可能注意到了,编辑器还有保存功能,上面配置的一个路径就是保存功能的路径
之后你可以写一个service 还是别的什么,来处理保存逻辑
我的是这样的
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode import com.ly.workflow.WorkflowProcessEngineFactory import org.activiti.engine.ActivitiException import org.activiti.engine.RepositoryService import org.activiti.engine.repository.Model import org.apache.batik.transcoder.TranscoderInput import org.apache.batik.transcoder.TranscoderOutput import org.apache.batik.transcoder.image.PNGTranscoder import org.ofbiz.base.util.Debug String modelId = parameters.modelId; String name = parameters.name; String des = parameters.description; String svgXml = parameters.svg_xml; String jsonXml = parameters.json_xml; RepositoryService repositoryService = WorkflowProcessEngineFactory.getRepositoryService(); ObjectMapper objectMapper = new ObjectMapper(); try { Model model = repositoryService.getModel(modelId); ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); modelJson.put("name", name); modelJson.put("description", des); model.setMetaInfo(modelJson.toString()); model.setName(name); repositoryService.saveModel(model); repositoryService.addModelEditorSource(model.getId(), jsonXml.getBytes("utf-8")); InputStream svgStream = new ByteArrayInputStream(svgXml.getBytes("utf-8")); TranscoderInput input = new TranscoderInput(svgStream); PNGTranscoder transcoder = new PNGTranscoder(); // Setup output ByteArrayOutputStream outStream = new ByteArrayOutputStream(); TranscoderOutput output = new TranscoderOutput(outStream); // Do the transformation transcoder.transcode(input, output); final byte[] result = outStream.toByteArray(); repositoryService.addModelEditorSourceExtra(model.getId(), result); outStream.close(); } catch (Exception e) { Debug.logError(e.getMessage(),"SaveProcessModelById.groovy"); }
因为流程图是生成出来的,所以调用activiti的接口比较多,具体的查一下activiti 的官方文档 或者是 看看一个叫咖啡兔的微博,很简单。
至此 整合完毕,其实还可以进一步进行封装与优化,并且把activiti explore 中的相关功能完善进去,这是一个整合其他框架的一个思路而已,其实spring 能整合的,ofbiz都能整合。这里不得不感叹ofbiz的强大。
相关推荐
这项工作主要目的在于利用Spring良好的系统集成能力,实现OFBiz与任意目标系统的整合与集成。在此项目中,OFBiz版本为11.04,而Activiti工作流引擎版本为5.9,Spring框架版本为3.1.1。何增耀在该文档中详细描述了...
主要目的是利用Spring的出色集成能力,使OFBiz能够与各种目标系统,特别是Activiti 5.9版本,进行无缝整合。这有助于扩展OFBiz的功能,使其能够支持复杂的业务流程管理。 2. **系统版本** - OFBiz版本为11.04,但...
cmd-bat-批处理-脚本-variables.zip
基于python+OpenCV和Mediapipe实现手语手势识别检测项目源码.zip 【项目说明】 1.多数小白下载后,在使用过程,可能会遇到些小问题,若自己解决不了,请及时私信描述你的问题,我会第一时间提供帮助,也可以远程指导 2.项目代码完整可靠,但难度适中,满足一些毕设、课设要求,且属于易上手的优质项目,项目内基本都有说明文档,按照操作即可,遇到困难也可私信交流 3.适用人群:各大计算机相关专业行业的在校学生、高校老师、公司程序员等下载使用 4.特别是那种爱钻研学习的学霸,强烈推荐此项目,可以二次开发提升自己。拿来作毕设、课设直接用也行,不过尽量弄懂项
cmd-bat-批处理-脚本-vcvars140.zip
苹果CMS后台影视微信小程序源码 带视频教程
新型武器装备作战需求论证方法与实践.zip
遗传算法优化BP神经网络(GABP)是一种结合了遗传算法(GA)和BP神经网络的优化预测方法。BP神经网络是一种多层前馈神经网络,常用于模式识别和预测问题,但其容易陷入局部最优。而遗传算法是一种模拟自然选择和遗传机制的全局优化方法,能够有效避免局部最优 。GABP算法通过遗传算法优化BP神经网络的权重和阈值,从而提高网络的学习效率和预测精度 。 种群:遗传算法中个体的集合,每个个体代表一种可能的解决方案。 编码:将解决方案转化为适合遗传操作的形式,如二进制编码。 适应度函数:用于评估个体解的质量,通常与目标函数相反,目标函数值越小,适应度越高。 选择:根据适应度保留优秀个体,常见方法有轮盘赌选择、锦标赛选择等。 交叉:两个父代个体交换部分基因生成子代。 变异:随机改变个体的部分基因,增加种群多样性。 终止条件:当迭代次数或适应度阈值达到预设值时停止算法 。 初始化种群:随机生成一组神经网络参数(权重和阈值)作为初始种群 。 计算适应度:使用神经网络模型进行训练和预测,根据预测误差计算适应度 。 选择操作:根据适应度选择优秀个体 。 交叉操作:对选择的个体进行交叉,生成新的子代个体 。 变异操作:对子代进行随机变异 。 替换操作:用新生成的子代替换掉一部分旧种群 。 重复步骤2-6,直到满足终止条件 。 适应度函数通常以预测误差为基础,误差越小,适应度越高。常用的误差指标包括均方根误差(RMSE)或平均绝对误差(MAE)等 。 GABP代码中包含了适应度函数的定义、种群的生成、选择、交叉、变异以及训练过程。代码注释详尽,便于理解每个步骤的作用 。 GABP算法适用于多种领域,如时间序列预测、经济预测、工程问题的优化等。它特别适合解决多峰优化问题,能够有效提高预测的准确性和稳定性 。
cmd-bat-批处理-脚本-hello world.zip
cmd-bat-批处理-脚本-Messagebox_Cancel_TryAgain_Continue.zip
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
qwq3 model 4 use for ollama
2025年系统集成项目管理工程师考试下午题精编.doc
内容概要:本文介绍了一种专为六节电池串联设计的模块化SOC主动均衡模型。该模型采用底层双向反激变换器和顶层buck-boost均衡的双重策略,旨在解决电池组中各节电池SOC不一致的问题。通过模块化设计,模型实现了灵活性和扩展性,适用于不同类型的电池组。文章详细介绍了模型的工作原理、设计思路以及仿真实验结果,验证了模型的有效性。 适合人群:从事电池管理系统的研发人员、电力电子工程师、科研工作者。 使用场景及目标:①研究电池组充放电均衡技术;②优化电池管理系统的设计;③作为论文创新和仿真实验的基础。 阅读建议:重点理解双向反激变换器和buck-boost均衡的具体实现方法及其协同工作的机制,结合仿真实验数据进一步验证模型效果。
cmd-bat-批处理-脚本-npx.zip
cmd-bat-批处理-脚本-str3.zip
《Java+SQL Server学生成绩管理系统》是一款融合了Java编程语言与SQL Server数据库技术的软件,专为高校或教育机构设计,用于高效管理学生的考试成绩。它具备数据录入、查询、统计分析等功能,旨在提升教学管理效率。 该系统的核心技术包括:一是Java后端开发。Java承担后端任务,处理HTTP请求、实现业务逻辑以及与数据库交互。项目可能借助Spring框架,利用其依赖注入、AOP等特性,简化开发流程。Spring MVC则助力实现MVC模式,处理Web请求。二是JSP技术。JSP是一种动态网页技术,页面融合HTML、CSS、JavaScript和Java代码,用于呈现用户界面及处理前端简单逻辑。三是SQL Server数据库。作为数据存储后端,SQL Server支持通过SQL语句完成表的创建、数据的增删改查等操作,还可借助存储过程和触发器提升功能与安全性。四是数据库设计。系统数据库设计关键,包含“学生”“课程”“成绩”等表,通过主外键关联数据,如“学生”表与“成绩”表通过学生ID关联,“课程”表与“成绩”表通过课程ID关联。五是B/S架构。采用浏览器/服务器架构,用户经Web浏览器访问系统,计算与数据处理在服务器端完成,降低客户端硬件要求。六是安全性。系统设置身份验证与授权机制,如登录验证,确保信息访问安全。同时,为防范SQL注入等威胁,采用预编译语句或ORM框架处理SQL命令。七是异常处理。Java的异常处理机制可捕获运行时问题,保障系统稳定性与用户体验。八是报表统计功能。系统具备成绩统计功能,如计算平均分、排名、及格率等,常使用聚合函数(SUM、AVG、COUNT等)和GROUP BY语句。九是设计模式。开发中可能运用单例模式、工厂模式等,提升代码可维护性和复用性。十是版本控制。项目可能使用Git等版本控制系统,便于团队协作与代码管理。 该学生成绩管理
cmd-bat-批处理-脚本-prog.zip
基于visualstudio2010,包括所有源代码,可以运行, 编程实现直线的 DDA 算法及 Bresenham 算法绘制任意斜率的直线。 设计一个图形并调用 1 中的 Bresenham 算法程序绘制。
cmd-bat-批处理-脚本-file.zip