整合Activiti Modeler到业务系统(或BPM平台)
1. 为什么要整合
Activiti 5.10版本把原本独立的Activiti Modeler模块整合到了Activiti Explorer中,两者相结合使用起来很方便,通过Modeler设计的流程模型可以直接部署到引擎,也可以把已经部署的流程转换为Model从而在Modeler中编辑。
在实际应用中也有这样的需求,把Modeler整合到业务系统中可以供管理员使用,或者作为BPM平台的一部分存在,很遗憾官方没有给出如何整合Modeler的文档。
2. 整合工作
2.1 下载源码
首先需要从Github下载源码:https://github.com/Activiti/Activiti;可以直接用Git克隆,也可以下载zip格式的压缩包。
2.2 复制文件
复制的所有文件均在activiti-webapp-explorer2目录中。
- src/main/resources中的editor.html、stencilset.json、plugins.xml到项目源码的源码根目录,保证编译之后在classes根目录
- src/main/webapp中的api、editor、explorer、libs到项目的webapp目录(与WEB-INF目录同级)
2.3 添加依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
< dependency >
< groupid >org.activiti</ groupid >
< artifactid >activiti-explorer</ artifactid >
< version >5.14</ version >
< exclusions >
< exclusion >
< artifactid >vaadin</ artifactid >
< groupid >com.vaadin</ groupid >
</ exclusion >
< exclusion >
< artifactid >dcharts-widget</ artifactid >
< groupid >org.vaadin.addons</ groupid >
</ exclusion >
< exclusion >
< artifactid >activiti-simple-workflow</ artifactid >
< groupid >org.activiti</ groupid >
</ exclusion >
</ exclusions >
</ dependency >
< dependency >
< groupid >org.activiti</ groupid >
< artifactid >activiti-modeler</ artifactid >
< version >5.14</ version >
</ dependency >
|
2.4 添加Java类
添加一个ExplorerRestApplication.java类保存到项目中,注册了一些REST路由。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package org.activiti.explorer.rest.application;
import org.activiti.editor.rest.application.ModelerServicesInit;
import org.activiti.rest.api.DefaultResource;
import org.activiti.rest.application.ActivitiRestApplication;
import org.activiti.rest.filter.JsonpFilter;
import org.restlet.Restlet;
import org.restlet.routing.Router;
public class ExplorerRestApplication extends ActivitiRestApplication {
public ExplorerRestApplication() {
super ();
}
/**
* Creates a root Restlet that will receive all incoming calls.
*/
@Override
public synchronized Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attachDefault(DefaultResource. class );
ModelerServicesInit.attachResources(router);
DiagramServicesInit.attachResources(router);
JsonpFilter jsonpFilter = new JsonpFilter(getContext());
jsonpFilter.setNext(router);
return jsonpFilter;
}
} |
2.5 配置web.xml
在web.xml文件中添加如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!-- Restlet adapter, used to expose modeler functionality through REST --> < servlet >
< servlet-name >RestletServlet</ servlet-name >
< servlet-class >org.restlet.ext.servlet.ServerServlet</ servlet-class >
< init-param >
<!-- Application class name -->
< param-name >org.restlet.application</ param-name >
< param-value >org.activiti.explorer.rest.application.ExplorerRestApplication</ param-value >
</ init-param >
</ servlet >
<!-- Catch all service requests --> < servlet-mapping >
< servlet-name >RestletServlet</ servlet-name >
< url-pattern >/service/*</ url-pattern >
</ servlet-mapping >
|
2.6 控制器
使用Spring MVC做了一个简单的封装,也可以使用其他的MVC实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package me.kafeitu.demo.activiti.web.workflow;
import java.io.ByteArrayInputStream;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
/** * 流程模型控制器
*
* @author henryyan
*/
@Controller @RequestMapping (value = "/workflow/model" )
public class ModelController {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
RepositoryService repositoryService;
/**
* 模型列表
*/
@RequestMapping (value = "list" )
public ModelAndView modelList() {
ModelAndView mav = new ModelAndView( "workflow/model-list" );
List<model> list = repositoryService.createModelQuery().list();
mav.addObject( "list" , list);
return mav;
}
/**
* 创建模型
*/
@RequestMapping (value = "create" )
public void create( @RequestParam ( "name" ) String name, @RequestParam ( "key" ) String key, @RequestParam ( "description" ) String description,
HttpServletRequest request, HttpServletResponse response) {
try {
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode editorNode = objectMapper.createObjectNode();
editorNode.put( "id" , "canvas" );
editorNode.put( "resourceId" , "canvas" );
ObjectNode stencilSetNode = objectMapper.createObjectNode();
editorNode.put( "stencilset" , stencilSetNode);
Model modelData = repositoryService.newModel();
ObjectNode modelObjectNode = objectMapper.createObjectNode();
modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1 );
description = StringUtils.defaultString(description);
modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelData.setMetaInfo(modelObjectNode.toString());
modelData.setName(name);
modelData.setKey(StringUtils.defaultString(key));
repositoryService.saveModel(modelData);
repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes( "utf-8" ));
response.sendRedirect(request.getContextPath() + "/service/editor?id=" + modelData.getId());
} catch (Exception e) {
logger.error( "创建模型失败:" , e);
}
}
/**
* 根据Model部署流程
*/
@RequestMapping (value = "deploy/{modelId}" )
public String deploy( @PathVariable ( "modelId" ) String modelId, RedirectAttributes redirectAttributes) {
try {
Model modelData = repositoryService.getModel(modelId);
ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
byte [] bpmnBytes = null ;
BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
bpmnBytes = new BpmnXMLConverter().convertToXML(model);
String processName = modelData.getName() + ".bpmn20.xml" ;
Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes)).deploy();
redirectAttributes.addFlashAttribute( "message" , "部署成功,部署ID=" + deployment.getId());
} catch (Exception e) {
logger.error( "根据模型部署流程失败:modelId={}" , modelId, e);
}
return "redirect:/workflow/model/list" ;
}
/**
* 导出model的xml文件
*/
@RequestMapping (value = "export/{modelId}" )
public void export( @PathVariable ( "modelId" ) String modelId, HttpServletResponse response) {
try {
Model modelData = repositoryService.getModel(modelId);
BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
byte [] bpmnBytes = xmlConverter.convertToXML(bpmnModel);
ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
IOUtils.copy(in, response.getOutputStream());
String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml" ;
response.setHeader( "Content-Disposition" , "attachment; filename=" + filename);
response.flushBuffer();
} catch (Exception e) {
logger.error( "导出model的xml文件失败:modelId={}" , modelId, e);
}
}
} </model> |
2.7 注意事项
如果使用Spring代理引擎,并且在项目中同时有activiti.cfg.xml文件(不管在main/resources还是test/resources目录),在activiti.cfg.xml里面的引擎中添加下面的配置参数,否则会导致打开Modeler的编辑页面时读取数据返回204状态码。
1
|
< property name = "processEngineName" value = "test" ></ property >
|
引擎默认名称为default,ProcessEngines.getDefaultProcessEngine()查询时会先检索main/resources,然后再检索test/resources的activiti.cfg.xml和activiti-context.xml文件,所以当main/resources监测不到指定文件时就会导致该引擎被当做web应用的引擎对象,这样会导致有两个引擎,所以把引擎的名称改为非默认的“default”。
3. 中文乱码问题解决办法
在JVM参数中添加参数:
-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8
参考:在Activiti Modeler中设计的流程包含奇数个中文时不能部署问题
4. 效果截图
在最新的kft-activiti-demo版本(1.7.0)中已经集成了Activiti Modeler,可以在线访问,也可以下载源码学习如何配置。
登录http://demo.kafeitu.me/kft-activiti-demo后选择流程管理->模型工作区菜单项即可。
相关推荐
在本实例中,我们将探讨如何将这两个优秀框架整合起来,利用 Activiti Modeler 在 Spring Boot 应用中实现业务流程的可视化设计和执行。 首先,我们需要理解 Spring Boot 如何配置 Activiti。在 Spring Boot 项目中...
Activiti 是一个开源的工作流和业务流程管理(BPM)系统,主要用于自动化业务流程。将 Activiti 集成到 Spring Boot 中,可以方便地在应用程序中实现工作流控制,提升业务流程的灵活性和可维护性。 在本实例中,...
Activiti Modeler 集成是企业流程管理(BPM)领域中的一个重要概念,它涉及到将Activiti Modeler工具与其他系统或平台进行整合,以便更有效地设计、部署和执行业务流程。Activiti Modeler是一款基于BPMN 2.0标准的...
7. 网页设计器整合:Activiti Modeler与SpringBoot应用无缝集成,用户在Web端即可进行全流程设计,降低了系统部署和使用的复杂度。 这个项目不仅提供了完整的流程管理功能,而且具有良好的扩展性和可定制性,对于...
SpringBoot 2.x 集成 Activiti 5.22 和 Modeler 可视化界面是一项常见的企业级应用开发任务,它涉及到流程自动化、微服务架构以及UI设计等多个技术领域。下面将详细介绍这个集成过程中的关键知识点。 首先,**...
为了提高流程设计的便捷性和效率,本篇文章将介绍如何整合activiti-modeler 5.21.0版,并对其进行二次封装,从而降低开发难度。下面将详细介绍整个过程中的关键步骤。 **1. 复制activiti-explorer相关文件** 首先...
Activiti 是一款开源的工作流和业务流程管理(BPM)系统,它提供了丰富的功能,使得企业可以轻松地构建、部署和管理业务流程。本文将基于提供的"activiti-modeler-springboot-master"项目,深入探讨如何将 Activiti ...
Activiti 是一个开源的工作流和业务流程管理(BPM)系统,它提供了强大的流程定义、执行和监控能力。Spring Boot 则是基于 Spring 框架的轻量级开发工具,简化了 Spring 应用的初始搭建以及开发过程。将两者结合,...
然后,克隆或下载`activiti-modeler-springboot-master`项目,导入到IDE中。 2. **集成Activiti**:在SpringBoot应用中引入Activiti依赖,并配置数据库连接,以存储流程定义和实例。通过定义`@Configuration`类,...
而Activiti7则是一个流行的工作流引擎,它提供了流程定义、执行、监控等全面的功能,广泛应用于业务流程管理(BPM)系统中。本文将详细介绍如何将SpringBoot2与Activiti7进行整合,以实现高效灵活的业务流程自动化。...
Activiti 是一个开源的工作流和业务流程管理(BPM)平台,它被广泛用于构建企业级的应用程序。这个“activiti整合web”项目显然旨在演示如何将Activiti与Web应用程序结合,特别是通过Spring MVC框架来实现。下面我们...
Activiti是一款开源的工作流和业务流程管理(BPM)系统,它具有轻量级、高性能和易于使用的特性。在版本6.0中,Activiti提供了一套完整的流程建模、执行、监控和分析功能,支持BPMN 2.0标准,使得开发者可以方便地在...
Activiti 是一个开源的工作流和业务流程管理(BPM)平台,它被广泛用于企业级应用中以自动化业务流程。本示例展示了如何将 Activiti 5.21 版本与 Spring 框架4.15版本进行集成,以实现灵活、可扩展的流程控制。 在...
而Activiti是一款开源的工作流引擎,广泛应用于业务流程管理(BPM)系统中,提供了强大的流程定义和执行能力。本篇将深入探讨Jeecg-Boot如何集成Activiti,以及在实际项目中的应用。 1. **Jeecg-Boot 概述** Jeecg...
这个"activiti 基础 web项目 spring mvc.zip"压缩包文件显然是一个教学或示例项目,旨在帮助开发者了解如何在Spring MVC框架下整合Activiti进行流程自动化。 **1. Activiti简介** Activiti 是由Alfresco Software...
2. **模型与部署**:用户可以使用 Activiti Modeler 或其他支持BPMN的工具创建流程模型,然后将其部署到Activiti引擎,以便执行。 3. **流程实例(Process Instance)**:每个流程定义在运行时都会产生一个或多个...
3. **创建流程定义**:使用 Activiti 的建模工具(如 Activiti Modeler)或直接编写 BPMN 2.0 XML 文件定义业务流程。 4. **启动流程**:在 Service 层,通过流程引擎启动流程实例,传入必要的业务数据。 5. **处理...
Activiti是基于Java的企业流程管理(BPM)平台,它提供了一套完整的业务流程自动化解决方案。本篇将详细讲解基于Activiti 5.9版本的项目实例,该实例适用于初学者,以MySQL作为数据库,旨在帮助读者快速理解和应用...
SpringMVC 是 Spring 框架的一部分,用于构建灵活、可扩展的 Web 应用,而 Activiti 是一个开源的业务流程管理(BPM)和工作流引擎,它提供了一个强大的平台来设计、执行和监控业务流程。 在整合 SpringMVC 与 ...
Activiti 是一个开源的工作流和业务流程管理(BPM)平台,它被广泛用于企业级应用中,以实现流程自动化和提升工作效率。标题中的 "activiti-6.0.0.rar" 指的是 Activiti 的第六个主要版本的压缩包文件,这个版本可能...