当前位置: 代码迷 >> 综合 >> Activiti 工作流引擎 ~ 官方demo学习
  详细解决方案

Activiti 工作流引擎 ~ 官方demo学习

热度:74   发布时间:2023-12-08 17:37:12.0

Activiti 工作流引擎 官方demo学习

本文使用的Activiti版本为5.22.0

Activiti 官方网站

Activiti-5.22.0 源码

Vaadin 官方网站

Vaadin Web应用开发教程(3):Vaadin应用程序框架介绍

Activiti 官方demo中使用Vaadin作为前端框架进行页面展示

Activiti 官方下载的文件目录如下,在wars文件夹中提供了两个demo
这里写图片描述

解压activiti-explorer.war,文件结构如下
这里写图片描述

modeler.html是Activiti Modeler的编辑界面,如图:
这里写图片描述

属性配置文件
日志属性:log4j.properties
引擎属性:engine.properties
数据库属性:db.properties
ui.properties

spring配置文件
activiti-custom-context.xml
activiti-login-context.xml
activiti-ui-context.xml

org.activiti.explorer.conf java配置文件
这里写图片描述

org.activiti.explorer.servlet servlet文件
这里写图片描述

对应的java文件可以在源码中找到
这里写图片描述

web.xml

<listener><listener-class>org.activiti.explorer.servlet.WebConfigurer</listener-class>
</listener>

WebConfigurer.java

public class WebConfigurer implements ServletContextListener {
    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);public AnnotationConfigWebApplicationContext context;public void setContext(AnnotationConfigWebApplicationContext context) {this.context = context;}@Overridepublic void contextInitialized(ServletContextEvent sce) {ServletContext servletContext = sce.getServletContext();log.debug("Configuring Spring root application context");AnnotationConfigWebApplicationContext rootContext = null;if (context == null) {rootContext = new AnnotationConfigWebApplicationContext();rootContext.register(ApplicationConfiguration.class);rootContext.refresh();} else {rootContext = context;}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootContext);initSpring(servletContext, rootContext);log.debug("Web application fully configured");}/*** Initializes Spring and Spring MVC.*/private ServletRegistration.Dynamic initSpring(ServletContext servletContext, AnnotationConfigWebApplicationContext rootContext) {log.debug("Configuring Spring Web application context");AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext();dispatcherServletConfiguration.setParent(rootContext);dispatcherServletConfiguration.register(DispatcherServletConfiguration.class);log.debug("Registering Spring MVC Servlet");ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServletConfiguration));dispatcherServlet.addMapping("/service/*");dispatcherServlet.setLoadOnStartup(1);dispatcherServlet.setAsyncSupported(true);return dispatcherServlet;}@Overridepublic void contextDestroyed(ServletContextEvent sce) {log.info("Destroying Web application");WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext());AnnotationConfigWebApplicationContext gwac = (AnnotationConfigWebApplicationContext) ac;gwac.close();log.debug("Web application destroyed");}
}

contextInitialized()

rootContext.register(ApplicationConfiguration.class);

initSpring()

AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext();
dispatcherServletConfiguration.setParent(rootContext);
dispatcherServletConfiguration.register(DispatcherServletConfiguration.class);ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServletConfiguration));
dispatcherServlet.addMapping("/service/*");
dispatcherServlet.setLoadOnStartup(1);

ApplicationConfiguration.java

@Configuration
@PropertySources({@PropertySource(value = "classpath:db.properties", ignoreResourceNotFound = true),@PropertySource(value = "classpath:engine.properties", ignoreResourceNotFound = true)
})
@ComponentScan(basePackages = { "org.activiti.explorer.conf" })
@ImportResource({
   "classpath:activiti-ui-context.xml", "classpath:activiti-login-context.xml", "classpath:activiti-custom-context.xml"})
public class ApplicationConfiguration {
    }

activiti-custom-context.xml文件中的内容是被注释掉了,官方activiti-explorer demo 中利用org.activiti.explorer.conf.ActivitiEngineConfiguration.java文件进行了配置

DemoDataConfiguration.java文件用于初始化demo数据
JacksonConfiguration.java文件用于配制com.fasterxml.jackson.databind.ObjectMapper对象,activiti内部依赖于该对象

DispatcherServletConfiguration.java

@ComponentScan({
   "org.activiti.rest.editor", "org.activiti.rest.diagram"})
@EnableAsync
public class DispatcherServletConfiguration extends WebMvcConfigurationSupport {
    //...
}

这里写图片描述

StencilsetRestResource.java

@RestController
public class StencilsetRestResource {
    @RequestMapping(value="/editor/stencilset", method = RequestMethod.GET, produces = "application/json;charset=utf-8")public @ResponseBody String getStencilset() {InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json");try {return IOUtils.toString(stencilsetStream, "utf-8");} catch (Exception e) {throw new ActivitiException("Error while loading stencil set", e);}}
}

StencilsetRestResource类读取stencilset.json用于modeler.html初始化

ModelEditorJsonRestResource.java

@RequestMapping(value="/model/{modelId}/json", method = RequestMethod.GET, produces = "application/json")public ObjectNode getEditorJson(@PathVariable String modelId) {ObjectNode modelNode = null;Model model = repositoryService.getModel(modelId);//...if (StringUtils.isNotEmpty(model.getMetaInfo())) {modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());} else {modelNode = objectMapper.createObjectNode();modelNode.put(MODEL_NAME, model.getName());}modelNode.put(MODEL_ID, model.getId());ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(new String(repositoryService.getModelEditorSource(model.getId()), "utf-8"));modelNode.put("model", editorJsonNode);//...return modelNode;}

ModelEditorJsonRestResource类获取模型数据用于在modeler.html中编辑模型

ModelSaveRestResource.java

@RequestMapping(value="/model/{modelId}/save", method = RequestMethod.PUT)@ResponseStatus(value = HttpStatus.OK)public void saveModel(@PathVariable String modelId, @RequestBody MultiValueMap<String, String> values) {//...Model model = repositoryService.getModel(modelId);ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());modelJson.put(MODEL_NAME, values.getFirst("name"));modelJson.put(MODEL_DESCRIPTION, values.getFirst("description"));model.setMetaInfo(modelJson.toString());model.setName(values.getFirst("name"));repositoryService.saveModel(model);repositoryService.addModelEditorSource(model.getId(), values.getFirst("json_xml").getBytes("utf-8"));InputStream svgStream = new ByteArrayInputStream(values.getFirst("svg_xml").getBytes("utf-8"));TranscoderInput input = new TranscoderInput(svgStream);PNGTranscoder transcoder = new PNGTranscoder();// Setup outputByteArrayOutputStream outStream = new ByteArrayOutputStream();TranscoderOutput output = new TranscoderOutput(outStream);// Do the transformationtranscoder.transcode(input, output);final byte[] result = outStream.toByteArray();repositoryService.addModelEditorSourceExtra(model.getId(), result);outStream.close();//...}

ModelSaveRestResource类用于modeler.html保存

这里写图片描述

这里写图片描述

新建模型
这里写图片描述
创建按钮对应的后台逻辑
这里写图片描述

modeler.html 关闭按钮/保存退出按钮跳转路径设置
这里写图片描述
这里写图片描述

这里写图片描述
EditorProcessDefinitionDetailPanel.java
这里写图片描述
新建模型、导入、编辑模型、复制模型、删除模型、部署、导出模型 按钮(下拉列表)添加事件监听

这里写图片描述
这里写图片描述

  相关解决方案