springboot集成activiti6在线编辑器
最近做了整合了一個(gè)后端框架,基本功能都已經(jīng)完善了,于是想將工作流整合進(jìn)來(lái),主流的工作流框架之一 activiti。
第一步:引入了jar包依賴
?
<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter-basic</artifactId><version>6.0.0</version><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></exclusion><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></exclusion><exclusion><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId></exclusion></exclusions></dependency><!-- 流程數(shù)據(jù)和文件轉(zhuǎn)換 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-json-converter</artifactId><version>6.0.0</version><exclusions><exclusion><artifactId>org.activiti</artifactId><groupId>activiti-bpmn-model</groupId></exclusion><exclusion><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId></exclusion></exclusions></dependency><!-- Activiti 在線設(shè)計(jì) --><!-- https://mvnrepository.com/artifact/org.activiti/activiti-modeler --><dependency><groupId>org.activiti</groupId><artifactId>activiti-modeler</artifactId><version>5.23.0</version><exclusions><exclusion><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId></exclusion></exclusions></dependency>依賴配置中一定要將spring-security排除掉,不然請(qǐng)求會(huì)被攔截跳轉(zhuǎn)到spring的登錄驗(yàn)證界面,導(dǎo)致系統(tǒng)無(wú)法使用。
第二步:在springboot中配置activiti
activiti啟動(dòng)時(shí),會(huì)自動(dòng)部署classpath:/templates/下面的bpmn流程文件
這一步配置好后,理論上就可以啟動(dòng)項(xiàng)目,activiti會(huì)自動(dòng)創(chuàng)建所需的表
?
第三步:創(chuàng)建Bean并注入service,代碼如下
@Configuration public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration {@Beanpublic SpringProcessEngineConfiguration springProcessEngineConfiguration(DruidDataSource dataSource,PlatformTransactionManager platformTransactionManager){SpringProcessEngineConfiguration spec = new SpringProcessEngineConfiguration();spec.setDataSource(dataSource);spec.setTransactionManager(platformTransactionManager);spec.setDatabaseSchemaUpdate("true");Resource[] resources = null;// 啟動(dòng)自動(dòng)部署流程try {resources = new PathMatchingResourcePatternResolver().getResources("classpath*:processes/*.bpmn");} catch (IOException e) {e.printStackTrace();}spec.setDeploymentResources(resources);return spec;}@Beanpublic ProcessEngineFactoryBean processEngine(SpringProcessEngineConfiguration engineConfiguration){ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();processEngineFactoryBean.setProcessEngineConfiguration(engineConfiguration);return processEngineFactoryBean;}@Beanpublic RepositoryService repositoryService(ProcessEngineFactoryBean engineFactoryBean) throws Exception{return engineFactoryBean.getObject().getRepositoryService();}@Beanpublic RuntimeService runtimeService(ProcessEngineFactoryBean engineFactoryBean) throws Exception{return engineFactoryBean.getObject().getRuntimeService();}@Beanpublic TaskService taskService(ProcessEngineFactoryBean engineFactoryBean) throws Exception{return engineFactoryBean.getObject().getTaskService();}@Beanpublic HistoryService historyService(ProcessEngineFactoryBean engineFactoryBean) throws Exception{return engineFactoryBean.getObject().getHistoryService();}完成以上步驟,activiti工作流基本就可以正常運(yùn)行了,需要編寫基于activiti的service的流程接口,比如根據(jù)發(fā)布的流程來(lái)發(fā)起流程
第四步:集成modeler流程在線設(shè)計(jì)器
1.下載activiti6的源碼包
將源碼包中的activiti-6/war/activiti-explorer.war解壓
將文件夾內(nèi) diagram-viewer,editor-app,modeler.html拷貝到項(xiàng)目下,stencilset.json拷貝到classpath下
其中的editor-app目錄下的就是編輯器源碼,modeler.html是編輯器的首頁(yè)
diagram-viewer是跟蹤流程實(shí)例的,發(fā)起流程之后才能用到,比如生成流程圖等
還有一個(gè)名為stencilset.json和en.json的數(shù)據(jù)文件,該文件是界面顯示內(nèi)容的來(lái)源,都是英文,可以通過(guò)修改來(lái)漢化
在editor-app/app-cfg.js中配置一下項(xiàng)目的url,我項(xiàng)目的根路徑是/drea,配置如下
2.修改源碼
解壓名為activiti-6\libs\activiti-modeler-6-sources.jar的jar包,將StencilsetRestResource.java、ModelEditorJsonRestResource.java和ModelSaveRestResource.java三個(gè)文件拷貝到自己項(xiàng)目的controller目錄下
并且在這三個(gè)controller中都加上RequestMapping映射,RequestMapping的值為上述app-cfg.js中配置的相對(duì)路徑:
完成到這一步,不出意外就可以打開編輯頁(yè)面了,附上打開編輯頁(yè)面新增流程模板的代碼:
@RestController @RequestMapping("/activiti") public class ActivitiController {/*** 創(chuàng)建模型*/@RequestMapping("/create")public void create(HttpServletRequest request, HttpServletResponse response) {try {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();ObjectMapper objectMapper = new ObjectMapper();ObjectNode editorNode = objectMapper.createObjectNode();editorNode.put("id", "canvas");editorNode.put("resourceId", "canvas");ObjectNode stencilSetNode = objectMapper.createObjectNode();stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");editorNode.put("stencilset", stencilSetNode);Model modelData = repositoryService.newModel();ObjectNode modelObjectNode = objectMapper.createObjectNode();modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, "hello1111");modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);String description = "hello1111";modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);modelData.setMetaInfo(modelObjectNode.toString());modelData.setName("hello1111");modelData.setKey("12313123");//保存模型repositoryService.saveModel(modelData);repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + modelData.getId());} catch (Exception e) {System.out.println("創(chuàng)建模型失敗:");}}}在瀏覽器中訪問(wèn)http://localhost:8080/activiti/create
流程在線設(shè)計(jì)器界面以及可以出來(lái)了,但是這里保存時(shí)有個(gè)坑,保存的請(qǐng)求一直報(bào)400錯(cuò)誤,修改ModelSaveRestResource.java:
復(fù)制過(guò)來(lái)的源碼中是使用的@RestController,不是普通的http請(qǐng)求,我把它改成@Controller后可以正常保存了
完成以上步驟就可以正常生成流程模板了,不過(guò)流程都存在數(shù)據(jù)庫(kù)里面,可以將保存的模板直接發(fā)布使用,代碼如下:
/*** 根據(jù)Model部署流程*/@RequestMapping(value = "deploy/{modelId}")@ResponseBodypublic String deploy(@PathVariable("modelId") String modelId) {try {Model modelData = repositoryService.getModel(modelId);ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);String processName = modelData.getName() + ".bpmn20.xml";Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes,"UTF-8")).deploy();return "部署成功,部署ID=" + deployment.getId();} catch (Exception e) {LOGGER.error("根據(jù)模型部署流程失敗:modelId="+ modelId, e);return "部署流程失敗!流程圖錯(cuò)誤";}}數(shù)據(jù)庫(kù)中的流程模板可以調(diào)用activiti接口讀取出來(lái),生成后綴為.bpmn的xml格式文件,可做流程模板的導(dǎo)入和導(dǎo)出,根據(jù)數(shù)據(jù)庫(kù)中讀取的流程模板生成bpmn的代碼如下:
/*** 導(dǎo)出model對(duì)象為指定類型** @param modelId 模型ID* //@param type 導(dǎo)出文件類型(bpmn\json)*/@RequestMapping(value = "export/{modelId}")public void export(@PathVariable("modelId") String modelId,HttpServletResponse response) {try {Model modelData = repositoryService.getModel(modelId);BpmnJsonConverter jsonConverter = new BpmnJsonConverter();byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());String jsonModel = new String(bytes,"UTF-8");StringBuffer jsonBuff = new StringBuffer();jsonBuff.append("[").append(jsonModel).append(",").append(modelData.getMetaInfo()).append("]");JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);//ByteArrayInputStream in = new ByteArrayInputStream(jsonBuff.toString().getBytes("UTF-8"));BpmnXMLConverter xmlConverter = new BpmnXMLConverter();byte[] exportBytes = xmlConverter.convertToXML(bpmnModel,"UTF-8");String XML = new String(exportBytes,"UTF-8");String filename = bpmnModel.getMainProcess().getId() + ".bpmn";ByteArrayInputStream in = new ByteArrayInputStream(XML.getBytes("UTF-8"));response.setHeader("Content-Disposition", "attachment; filename="+ filename);IOUtils.copy(in, response.getOutputStream());response.flushBuffer();FileUtil.exportFile(response, in,filename);} catch (Exception e) {LOGGER.error("導(dǎo)出model的xml文件失敗!", e);}}以下是我自己做的一個(gè)流程模板在線維護(hù)的功能界面:
總結(jié)
以上是生活随笔為你收集整理的springboot集成activiti6在线编辑器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PHP常用函数总结(180多个)[持续更
- 下一篇: hadoop环境搭建总结