当前位置: 首页 > news >正文

Flowable7.x学习笔记(十四)查看部署流程Bpmn2.0-xml

前言

        Flowable 在其前端 Modeler 中,采用 BPMN 2.0 标准将流程中的任务、网关、事件等元素以 XML 形式存储,并附带图形互换(Diagram Interchange,DI)数据,以保证在前端与后端都能精准重建可视化流程图。

        生成的 .bpmn.bpmn20.xml 文件会随业务归档(BAR)一起部署到 Flowable 引擎,并被存储在数据库中。当部署完成后,流程引擎会读取并解析这些 XML 文件,构建内部执行模型,用于后续实例创建与任务调度。本文将采用后端API的方式将XML查询出来在前端界面展示。

一、XML展示的作用

① 可视化编辑

        由于 XML 文件包含 DI 信息,可借助 bpmn-js、Flowable Modeler 或其他 BPMN 渲染库,将其加载至前端,实时重现可拖拽的流程图界面,并支持恢复图元位置、节点属性等,方便在线修订。

② 审计与对比

        流程定义以文本 XML 形式存储后,可轻松纳入 Git 等版本控制工具,通过 diffblame 等功能直观查看变更记录,并支持快速回退、历史审计与协同评审。

二、XML展示的必要性

① 协作与共享

        导出后的 XML 文件可在设计、开发与运维团队之间共享,确保各方在同一流程版本上评审与协作,减少沟通成本与误解。

② 自动化测试与部署

        CI/CD 流水线可自动拉取并部署导出的 XML,触发集成测试和端到端验证,保证流程逻辑在不同环境中的一致性与可重复性。

③ 合规与审计

        在金融、医疗等高合规行业,需将流程定义以 XML 形式存档,供审计机构或内控团队查验。导出功能可生成可追溯的流程快照,证明流程设计未经篡改。

④ 平台互操作

        标准化的 BPMN 2.0 XML 文件能与 Camunda、jBPM 等第三方流程引擎互操作,便于跨平台迁移与系统整合,提升整体架构的灵活性。

三、后端完成查询功能

① 明确http请求参数

此处我们只需要部署的流程的定义ID,具体信息都由ID查询出来,保证数据的确定性

package com.ceair.entity.request;import lombok.Data;import java.io.Serial;
import java.io.Serializable;/*** @author wangbaohai* @ClassName QueryImageOrXmlReq* @description: 查询部署流程定义的图片或xml文件请求对象* @date 2025年04月22日* @version: 1.0.0*/
@Data
public class QueryImageOrXmlReq implements Serializable {@Serialprivate static final long serialVersionUID = 1L;/*** 流程定义ID*/private String processDefinitionId;}

② 创建服务接口

/*** 根据查询条件生成并返回查询的XML字符串* 此方法用于将查询条件封装对象转换为XML格式的字符串,以便进行后续的查询操作* 它接受一个包含查询条件的请求对象,可以是图像信息或XML格式的查询条件** @param queryImageOrXmlReq 包含查询条件的请求对象,可以是图像信息或XML格式的查询条件* @return 返回根据查询条件生成的XML字符串*/
String queryXML(QueryImageOrXmlReq queryImageOrXmlReq);

③ 实现服务接口

        此处是实现导出的核心部署,大致的思路是:接收一个包含 流程定义 ID 的请求对象,校验参数无误后,从 Flowable 的 RepositoryService 中读取对应流程定义的 XML 资源,最后将 XML 内容先进行 Base64 编码,再做 URL 安全转码返回给调用方。在整个过程中,通过详尽的日志和多层异常捕获,保证了调用链的可观察性与健壮性。

1)安全与健壮

参数校验 + 多层异常捕获,避免非法调用和运行时崩溃。

2)兼容前端

Base64 + URL 编码后的字符串,可直接在浏览器端 decodeURIComponent(atob(...)) 复原,适配多数 JS 环境。

3)可扩展

若 XML 内容较大,可考虑流式分块返回或引入压缩(如 GZIP)以降低网络带宽;对于高并发场景,可将 XML 缓存到 Redis 等中间件,减少对 Flowable 引擎的频繁访问。

具体代码如下:

/*** 根据流程定义ID查询流程XML信息** @param queryImageOrXmlReq 查询请求对象,包含流程定义ID* @return 返回流程XML的Base64编码字符串* @throws IllegalArgumentException 如果请求对象或流程定义ID为空* @throws BusinessException        如果流程定义不存在或读取资源时发生业务异常*/
@Override
public String queryXML(QueryImageOrXmlReq queryImageOrXmlReq) {// 参数校验:确保请求对象不为空if (queryImageOrXmlReq == null) {log.error("获取流程XML失败,原因:请求对象不能为空");throw new IllegalArgumentException("获取流程XML失败,原因:请求对象不能为空");}String processDefinitionId = queryImageOrXmlReq.getProcessDefinitionId();// 参数校验:确保流程定义ID不为空或空字符串if (processDefinitionId == null || processDefinitionId.trim().isEmpty()) {log.error("获取流程XML失败,原因:流程定义ID不能为空或空字符串");throw new IllegalArgumentException("获取流程XML失败,原因:流程定义ID不能为空或空字符串");}// 根据流程定义ID查询流程定义ActReProcdef actReProcdef = getById(processDefinitionId);if (actReProcdef == null) {log.error("获取流程XML失败,原因:流程定义不存在,流程定义ID:{}", processDefinitionId);throw new BusinessException("获取流程XML失败,原因:流程定义不存在,流程定义ID:" + processDefinitionId);}// 获取流程图资源流try (InputStream xmlStream = repositoryService.getResourceAsStream(actReProcdef.getDeploymentId(),actReProcdef.getResourceName())) {if (xmlStream == null) {log.error("获取流程XML失败,原因:资源流为空,流程定义ID:{}", processDefinitionId);throw new BusinessException("获取流程XML失败,原因:资源流为空,流程定义ID:" + processDefinitionId);}// 将资源流内容读取为字节数组并进行Base64编码ByteArrayOutputStream outputStream = new ByteArrayOutputStream();byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = xmlStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}// 使用 UrlEncoder 进行编码return URLEncoder.encode(Base64.getEncoder().encodeToString(outputStream.toByteArray()),StandardCharsets.UTF_8);} catch (IOException e) {// 捕获IO异常并记录日志log.error("获取流程XML失败,原因:IO异常,流程定义ID:{}", processDefinitionId, e);throw new BusinessException("获取流程XML失败,原因:IO异常", e);} catch (Exception e) {// 捕获其他未知异常并记录日志log.error("获取流程XML失败,原因:未知异常,流程定义ID:{}", processDefinitionId, e);throw new BusinessException("获取流程XML失败,原因:未知异常", e);}
}

④ 创建功能接口

// 使用Spring Security的注解进行权限控制,只有拥有特定权限的用户才能访问此方法
@PreAuthorize("hasAnyAuthority('/api/v1/actReProcdef/queryXml')")
// 定义参数对象的元数据,用于API文档生成
@Parameter(name = "queryImageOrXmlReq", description = "查询流程定义图片请求对象", required = true)
// 定义操作的元数据,用于API文档生成
@Operation(summary = "查询流程定义XML")
// 声明这是一个POST类型的HTTP请求处理方法
@PostMapping("/queryXml")
public Result<String> queryXML(@RequestBody QueryImageOrXmlReq queryImageOrXmlReq) {try {// 调用服务层方法执行流程定义操作,传入请求对象并获取操作结果String xml = actReProcdefService.queryXML(queryImageOrXmlReq);// 返回操作成功的响应结果return Result.success(xml);} catch (Exception e) {// 捕获异常,记录详细的错误日志,并返回包含失败原因的响应结果log.error("查询流程定义XML失败 具体原因为 : {}", e.getMessage());return Result.error("查询流程定义XML失败,失败原因:" + e.getMessage());}
}

四、前端完成查询功能

① 安装 XML 美化插件

        本文采用Vue3的美化插件-pretty-xml-vue3,各位可以选择其他工具,使用方法各工具根据官方文档即可。

安装命令:yarn add pretty-xml-vue3 -D

安装结果:

② 引入样式

在 main.ts 引入样式【import "pretty-xml-vue3/style.css"】,此步骤不可跳过,否则高亮配色不会生效

③ 声明declare 

此步骤是解决type校验错误提示

// pretty-xml-vue3

declare module 'pretty-xml-vue3';

④ 创建接口

// 查询流程定义的xml
export function queryXml(data: QueryImageOrXmlReq) {return request.post<any>({url: '/pm-process/api/v1/actReProcdef/queryXml',data,})
}

⑤ index.vue 引入xml工具

// 引入 xml 美化工具

import { PrettyXml } from 'pretty-xml-vue3'

⑥ 创建查看xml按钮方法

/*** 异步函数:用于显示流程定义的 XML 信息** @param data ActReProcdefVO 类型的对象,包含流程定义的相关信息*/
async function onShowXml(data: ActReProcdefVO) {try {// 组装查询参数,包括流程定义 IDconst param: QueryImageOrXmlReq = {processDefinitionId: data.id,}// 调用后端接口获取流程定义的 XML 数据const result: any = await queryXml(param)// 判断查询结果是否成功if (result.success && result.code === 200) {// 第一步:URL 解码,得到 Base64const base64Str: string = decodeURIComponent(result.data)// 第二步:Base64 解码为二进制字符串const binaryStr = atob(base64Str)// 第三步:转为 UTF-8 文本const bytes = Uint8Array.from(binaryStr, c => c.charCodeAt(0))// 获取数据xmlData.value = new TextDecoder('utf-8').decode(bytes)// 打开 XML 对话框showXml.value = true}else {// 提示操作失败的错误提示信息ElMessage({message: `查询失败原因:${result.message}`,})}}catch (error) {// 捕获异常并提取错误信息let errorMessage = '未知错误'if (error instanceof Error) {errorMessage = error.message}// 显示操作失败的错误提示信息ElMessage({message: `查询失败: ${errorMessage || '未知错误'}`,type: 'error',})}
}

⑦ 创建查询xml按钮

⑧ 创建xml展示区域

此处需要说明的是,这里使用了xml美化工具,需要指定标签 【PrettyXml】

  <!-- XML 展示弹出框 --><el-dialog v-model="showXml" title="XML 展示" width="30%"><div class="xml-container"><PrettyXml :xml="xmlData" :options="{ shortRecord: true }" /></div></el-dialog>

.xml-container {

  min-height: 300px;

  max-height: 600px;

  width: 100%;

  overflow-x: unset;

  overflow-y: scroll;

}

五、分配权限

① 新增按钮

② 分配权限

给当前admin用户的角色【超级管理员】分配按钮权限

六、结果验证

 七、后记

本篇文章的前后端仓库地址请查询专栏第一篇文章,后续打算把xml和流程图片展示出来

本文的后端分支是 process-7

本文的前端分支是 process-9

相关文章:

  • 【MySQL】(8) 联合查询
  • 【DE-III】基于细节增强的模态内和模态间交互的视听情感识别
  • 图像修复模型MAT(Mask-Aware Transformer)的训练、推理实战记录
  • 深入掌握Redis主从复制:原理、配置与生产级实践指南
  • python_BeautifulSoup提取html中的信息
  • 4G卡的DTU固件TCP通讯
  • MySQL 从入门到精通
  • C++23 中 constexpr 的重要改动
  • 【每天一个知识点】IPv4(互联网协议版本4)和IPv6(互联网协议版本6)
  • [贪心_7] 最优除法 | 跳跃游戏 II | 加油站
  • Unity | AmplifyShaderEditor插件基础(第三集:颜色的计算)
  • 高效DCDC电源芯片在运动控制器中的应用:设计考量、性能评估与可靠性分析
  • TortoiseGit使用图解
  • Linux进程学习【基本认知】
  • echarts坐标轴数值,生成的数值是0,100,200,300...,怎么不设置min和max的情况下,让坐标轴的数值相隔200
  • TestBrain开源程序是一款集使用AI(如deepseek)大模型自动生成测试用例、和测试用例评审、RAG知识库管理的web平台系统
  • 常见网络安全攻击类型深度剖析(三):DDoS攻击——分类、攻击机制及企业级防御策略
  • 《深入理解计算机系统》阅读笔记之第十一章 网络编程
  • React.memo 和 useMemo
  • 【金仓数据库征文】- 深耕国产数据库优化,筑牢用户体验新高度
  • 人民日报:广东全力推动外贸稳量提质
  • 艺术与医学的对话,瑞金医院办了一个展览
  • “冲刺万亿城市”首季表现如何?温州领跑,大连GDP超徐州
  • 坤莹·帕塔玛·利斯达特拉任世界羽联主席
  • 金隅集团:今年拿地将选择核心热门地块,稳健审慎投资
  • 俄方证实俄总统普京正在会见美特使威特科夫