Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler 流程配置可视化(超详细)[通俗易懂]

您所在的位置:网站首页 flowable自定义表单页面 Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler 流程配置可视化(超详细)[通俗易懂]

Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler 流程配置可视化(超详细)[通俗易懂]

2024-07-16 13:37| 来源: 网络整理| 查看: 265

大家好,又见面了,我是你们的朋友全栈君。

Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler 流程配置可视化(超详细)版本加依赖加配置内部日志初始化 ProcessEngine 代码初始化flowable.cfg.xml 初始化我的初始化示例集成 Flowable Modeler 下载源码文件位置新增依赖代码集成 前端代码集成后端代码集成结构代码修改 ApplicationConfiguration 修改AppDispatcherServletConfiguration 修改SecurityUtils 修改新增 getAccount 接口url-config.js 修改StencilSetResource汉化启动器修改访问页面关闭数据库自动更新自身 XML 扫描不到的问题结尾版本

这里选择的版本为 6.4.1

Flowable 6.4.1 release

中文版用户手册:Flowable BPMN 用户手册

如果需要集成 Flowable Modeler 的请下载源码

PS:不要选择 6.4.2 版本,这个版本有发版问题

加依赖

由于是 spring-boot 集成,因此直接选择 flowable-spring-boot-starter,里面提供了齐全的 REST API

代码语言:javascript复制 org.flowable flowable-spring-boot-starter 6.4.1

其他的也可以直接选择 flowable-engine

代码语言:javascript复制 org.flowable flowable-engine 6.4.1 加配置代码语言:javascript复制# flowable 配置 flowable: # 关闭异步,不关闭历史数据的插入就是异步的,会在同一个事物里面,无法回滚 # 开发可开启会提高些效率,上线需要关闭 async-executor-activate: false内部日志

Flowable 使用 SLF4J 作为内部日志框架。在这个例子中,我们使用 log4j 作为 SLF4J 的实现。

加依赖

代码语言:javascript复制 org.slf4j slf4j-api 1.7.21 org.slf4j slf4j-log4j12 1.7.21

resource 目录下新建文件 log4j.properties

代码语言:javascript复制log4j.rootLogger=DEBUG, CA log4j.appender.CA=org.apache.log4j.ConsoleAppender log4j.appender.CA.layout=org.apache.log4j.PatternLayout log4j.appender.CA.layout.ConversionPattern= %d{ hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n初始化 ProcessEngine代码初始化代码语言:javascript复制// 流程引擎配置 ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl(url) .setJdbcUsername(username) .setJdbcPassword(password) .setJdbcDriver(driverClassName) // 初始化基础表,不需要的可以改为 DB_SCHEMA_UPDATE_FALSE .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); // 初始化流程引擎对象 ProcessEngine processEngine = cfg.buildProcessEngine();flowable.cfg.xml 初始化

代码部分

代码语言:javascript复制// 流程引擎配置 ProcessEngineConfiguration cfg = ProcessEngineConfiguration // 根据文件名获取配置文件 //.createProcessEngineConfigurationFromResource("activiti.cfg.xml"); // 获取默认配置文件,默认的就是 activiti.cfg.xml .createProcessEngineConfigurationFromResourceDefault() // 初始化基础表,不需要的可以改为 DB_SCHEMA_UPDATE_FALSE .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); // 初始化流程引擎对象 ProcessEngine processEngine = cfg.buildProcessEngine();

新建 flowable.cfg.xml

代码语言:javascript复制 我的初始化示例

我的配置文件 ProcessEngineConfig.java

依赖

spring-boot-configuration-processor 加载配置文件lomok 简化 java 代码代码语言:javascript复制 org.springframework.boot spring-boot-configuration-processor org.projectlombok lombok 1.18.0 provided 代码语言:javascript复制/** * 流程引擎配置文件 * @author: linjinp * @create: 2019-10-21 16:49 **/ @Configuration @ConfigurationProperties(prefix = "spring.datasource") @Data public class ProcessEngineConfig { private Logger logger = LoggerFactory.getLogger(ProcessEngineConfig.class); @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.publicKey}") private String publicKey; /** * 初始化流程引擎 * @return */ @Primary @Bean(name = "processEngine") public ProcessEngine initProcessEngine() { logger.info("=============================ProcessEngineBegin============================="); // 流程引擎配置 ProcessEngineConfiguration cfg = null; try { cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl(url) .setJdbcUsername(username) .setJdbcPassword(ConfigTools.decrypt(publicKey, password)) .setJdbcDriver(driverClassName) // 初始化基础表,不需要的可以改为 DB_SCHEMA_UPDATE_FALSE .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE) // 默认邮箱配置 // 发邮件的主机地址,先用 QQ 邮箱 .setMailServerHost("smtp.qq.com") // POP3/SMTP服务的授权码 .setMailServerPassword("xxxxxxx") // 默认发件人 .setMailServerDefaultFrom("[email protected]") // 设置发件人用户名 .setMailServerUsername("管理员") // 解决流程图乱码 .setActivityFontName("宋体") .setLabelFontName("宋体") .setAnnotationFontName("宋体"); } catch (Exception e) { e.printStackTrace(); } // 初始化流程引擎对象 ProcessEngine processEngine = cfg.buildProcessEngine(); logger.info("=============================ProcessEngineEnd============================="); return processEngine; } }

PS:这里没有单独对流程引擎中的 8 个核心服务做初始化,是因为使用 flowable-spring-boot-starter 依赖,会自动帮忙注册好,不需要自己再注册,直接使用即可

如果你使用的依赖是 flowable-engine,你可能还需要

代码语言:javascript复制//八大接口 // 业务流程的定义相关服务 @Bean public RepositoryService repositoryService(ProcessEngine processEngine){ return processEngine.getRepositoryService(); } // 流程对象实例相关服务 @Bean public RuntimeService runtimeService(ProcessEngine processEngine){ return processEngine.getRuntimeService(); } // 流程任务节点相关服务 @Bean public TaskService taskService(ProcessEngine processEngine){ return processEngine.getTaskService(); } // 流程历史信息相关服务 @Bean public HistoryService historyService(ProcessEngine processEngine){ return processEngine.getHistoryService(); } // 表单引擎相关服务 @Bean public FormService formService(ProcessEngine processEngine){ return processEngine.getFormService(); } // 用户以及组管理相关服务 @Bean public IdentityService identityService(ProcessEngine processEngine){ return processEngine.getIdentityService(); } // 管理和维护相关服务 @Bean public ManagementService managementService(ProcessEngine processEngine){ return processEngine.getManagementService(); } // 动态流程服务 @Bean public DynamicBpmnService dynamicBpmnService(ProcessEngine processEngine){ return processEngine.getDynamicBpmnService(); } //八大接口 end集成 Flowable Modeler下载源码

版本为 6.4.1,不多说了,看文章开头下载源码

文件位置

打开文件夹 flowable-ui-modeler

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler

flowable-ui-modeler-app:主要为前端界面,文件在 resource/static 下flowable-ui-modeler-conf:主要为一些配置文件 Configurationflowable-ui-modeler-logic:主要为一些业务逻辑还有 SQLflowable-ui-modeler-rest:主要为 rest 接口

这些都是需要用到的

新增依赖

使用 rest,logic,conf 的依赖

代码语言:javascript复制 org.flowable flowable-ui-modeler-rest 6.4.1 org.flowable flowable-ui-modeler-logic 6.4.1 org.flowable flowable-ui-modeler-conf 6.4.1 代码集成前端代码集成

在项目中的 resource 文件夹下新建一个 static 文件夹

SpringBoot 能自动读取 static 目录下的静态文件,因此文件夹名称不可随意更改

复制 flowable-ui-modeler-app 包中 resources\static 下所有文件,复制到新建的 static 下

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-app\src\main\resources\static

在这里插入图片描述在这里插入图片描述后端代码集成

复制以下文件到自己的项目中

ApplicationConfiguration.java

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-conf\src\main\java\org\flowable\ui\modeler\conf

原因:这个文件是启动中必要的配置文件,需要做修改,详细的可以看下 app 中启动类,文件路径随意

AppDispatcherServletConfiguration.java

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-conf\src\main\java\org\flowable\ui\modeler\servlet

原因:这个文件是启动中必要的配置文件,需要做修改,详细的可以看下 app 中启动类,文件路径随意

StencilSetResource.java

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-rest\src\main\java\org\flowable\ui\modeler\rest\app

同时在 resource 下新建一个 stencilset 文件夹用来放汉化文件,可以直接下载我上传的

原因:国际化配置加载,为了使用我们自己的汉化文件因此把文件拿出来并修改,文件路径随意

PS:复制出来后要对这个文件进行重命名,否则会与 Jar 包里的文件产生 Bean 存在的冲突

我这重命名后叫 FlowableStencilSetResource.java

SecurityUtils

路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-common\src\main\java\org\flowable\ui\common\security

原因:流程模型加载需要调用的工具类,文件路径需要与原路径保持一致

也就是包路径必须是 org.flowable.ui.common.security 这样在 Jar 中的方法在调用时会覆盖原 Jar 里的工具类

结构在这里插入图片描述在这里插入图片描述代码修改ApplicationConfiguration 修改

此文件不需要过多说明,主要移除 IDM 方面的配置

注意 conf 目录不要引入,里面也包含和 IDM 相关的配置

代码语言:javascript复制@Configuration @EnableConfigurationProperties(FlowableModelerAppProperties.class) @ComponentScan(basePackages = { // "org.flowable.ui.modeler.conf", // 不引入 conf "org.flowable.ui.modeler.repository", "org.flowable.ui.modeler.service", // "org.flowable.ui.modeler.security", //授权方面的都不需要 // "org.flowable.ui.common.conf", // flowable 开发环境内置的数据库连接 // "org.flowable.ui.common.filter", // IDM 方面的过滤器 "org.flowable.ui.common.service", "org.flowable.ui.common.repository", // // "org.flowable.ui.common.security",//授权方面的都不需要 "org.flowable.ui.common.tenant" },excludeFilters = { // 移除 RemoteIdmService @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RemoteIdmService.class) } ) public class ApplicationConfiguration { @Bean public ServletRegistrationBean modelerApiServlet(ApplicationContext applicationContext) { AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext(); dispatcherServletConfiguration.setParent(applicationContext); dispatcherServletConfiguration.register(ApiDispatcherServletConfiguration.class); DispatcherServlet servlet = new DispatcherServlet(dispatcherServletConfiguration); ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, "/api/*"); registrationBean.setName("Flowable Modeler App API Servlet"); registrationBean.setLoadOnStartup(1); registrationBean.setAsyncSupported(true); return registrationBean; } }AppDispatcherServletConfiguration 修改

同理,为了不引入 IDM 的配置

代码语言:javascript复制@Configuration @ComponentScan(value = { "org.flowable.ui.modeler.rest.app", // 不加载 rest,因为 getAccount 接口需要我们自己实现 // "org.flowable.ui.common.rest" },excludeFilters = { // 移除 EditorUsersResource 与 EditorGroupsResource,因为不使用 IDM 部分 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorUsersResource.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorGroupsResource.class), // 配置文件用自己的 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = StencilSetResource.class), } ) @EnableAsync public class AppDispatcherServletConfiguration implements WebMvcRegistrations { private static final Logger LOGGER = LoggerFactory.getLogger(AppDispatcherServletConfiguration.class); @Bean public SessionLocaleResolver localeResolver() { return new SessionLocaleResolver(); } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LOGGER.debug("Configuring localeChangeInterceptor"); LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("language"); return localeChangeInterceptor; } @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { LOGGER.debug("Creating requestMappingHandlerMapping"); RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping(); requestMappingHandlerMapping.setUseSuffixPatternMatch(false); requestMappingHandlerMapping.setRemoveSemicolonContent(false); Object[] interceptors = { localeChangeInterceptor() }; requestMappingHandlerMapping.setInterceptors(interceptors); return requestMappingHandlerMapping; } }SecurityUtils 修改

这个主要保存时候会调这里的接口

将 getCurrentUserObject 方法进行修改,让他获取默认的 admin

代码语言:javascript复制/** * @return the {@link User} object associated with the current logged in user. */ public static User getCurrentUserObject() { if (assumeUser != null) { return assumeUser; } RemoteUser user = new RemoteUser(); user.setId("admin"); user.setDisplayName("Administrator"); user.setFirstName("Administrator"); user.setLastName("Administrator"); user.setEmail("[email protected]"); user.setPassword("123456"); List pris = new ArrayList(); pris.add(DefaultPrivileges.ACCESS_MODELER); pris.add(DefaultPrivileges.ACCESS_IDM); pris.add(DefaultPrivileges.ACCESS_ADMIN); pris.add(DefaultPrivileges.ACCESS_TASK); pris.add(DefaultPrivileges.ACCESS_REST_API); user.setPrivileges(pris); return user; }新增 getAccount 接口

新建文件 FlowableController,自己随意

在加载页面时候会调用这个接口获取用户信息,由于我们绕过了登陆,因此给个默认的用户 admin

为了不和原文件冲突,所以 @RequestMapping("/login")

代码语言:javascript复制/** * Flowable 相关接口 * @author linjinp * @date 2019/10/31 10:55 */ @RestController @RequestMapping("/login") public class FlowableController { /** * 获取默认的管理员信息 * @return */ @RequestMapping(value = "/rest/account", method = RequestMethod.GET, produces = "application/json") public UserRepresentation getAccount() { UserRepresentation userRepresentation = new UserRepresentation(); userRepresentation.setId("admin"); userRepresentation.setEmail("[email protected]"); userRepresentation.setFullName("Administrator"); // userRepresentation.setLastName("Administrator"); userRepresentation.setFirstName("Administrator"); List privileges = new ArrayList(); privileges.add(DefaultPrivileges.ACCESS_MODELER); privileges.add(DefaultPrivileges.ACCESS_IDM); privileges.add(DefaultPrivileges.ACCESS_ADMIN); privileges.add(DefaultPrivileges.ACCESS_TASK); privileges.add(DefaultPrivileges.ACCESS_REST_API); userRepresentation.setPrivileges(privileges); return userRepresentation; } }url-config.js 修改

路径:resource\static\scripts\configuration\url-conf.js

将 getAccountUrl 的路径改为上面自己的 getAccount 接口的路径

在这里插入图片描述在这里插入图片描述StencilSetResource汉化

记得重命名,我这重命名后叫 FlowableStencilSetResource

把配置文件路径改为我们自己目录下的路径

stencilset/stencilset_bpmn.json 与 stencilset/stencilset_cmmn.json

在这里插入图片描述在这里插入图片描述启动器修改

主要修改三个

引入 自己目录 下的 ApplicationConfiguration 与 AppDispatcherServletConfiguration,可参考 app 的启动器引入 Jar 包 里的 DatabaseConfiguration,这个文件是对表进行更新的,由于 conf 目录不引入,因此我们只能单独引入,具体内容可以自己看下这个文件移除 Security 自动配置 Spring Cloud 为 Finchley 版本:@SpringBootApplication(exclude={SecurityAutoConfiguration.class})Spring Cloud 为 Greenwich 版本:@SpringBootApplication(exclude={SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class})代码语言:javascript复制//启用全局异常拦截器 @Import(value={ // 引入修改的配置 ApplicationConfiguration.class, AppDispatcherServletConfiguration.class, // 引入 DatabaseConfiguration 表更新转换 DatabaseConfiguration.class}) // Eureka 客户端 @EnableDiscoveryClient @ComponentScan(basePackages = { "com.springcloud.*"}) @MapperScan("com.springcloud.*.dao") // 移除 Security 自动配置 // Spring Cloud 为 Finchley 版本 // @SpringBootApplication(exclude={SecurityAutoConfiguration.class}) // Spring Cloud 为 Greenwich 版本 @SpringBootApplication(exclude={ SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class}) public class FlowableApplication { public static void main(String[] args) { SpringApplication.run(FlowableApplication.class, args); } }访问页面

http://localhost:8087/

自动跳转

在这里插入图片描述在这里插入图片描述关闭数据库自动更新在这里插入图片描述在这里插入图片描述

创建完数据库后,关闭自动更新。原因是更新的标准并非是你引入的流程引擎的版本,而是官方发布的版本,所以如果一直开启,以后重启之类的可能导致提示版本升级失败,毕竟你的依赖版本并没有升级。

代码语言:javascript复制Factory method 'initProcessEngine' threw exception; nested exception is org.flowable.common.engine.api.FlowableException: Could not update Flowable database schema: unknown version from database: '6.5.0.1'

因此除非你确实要提高你的引擎版本到最新,否则不要开启

假如你出现了上述问题,可尝试: 1.删掉所有表重建 这样会创建你当前版本的数据库,这种肯定可以,但是基本上数据是没了,除非你有耐心迁移下。

2.直接修改当前数据库版本 就是这张 ACT_GE_PROPERTY 的数据,如果出问题了,这里的版本就会变成更新的版本,如:6.5.0.1,状态从创建变为更新,手动直接修正所有参数。本人没尝试过这种方式,应该可行。

在这里插入图片描述在这里插入图片描述自身 XML 扫描不到的问题

首页不建议将业务代码和流程引擎混在一个项目中

如果一定要这样,遇到自己的 XML 总扫描不到,转下面的文章

SpringBoot 集成 Flowable + Flowable Modeler 导致自身 XML 扫描不到解决方案

结尾

文章如果存在什么问题,请及时留言反馈

集成后的代码:https://gitee.com/linjinp-spring-cloud/linjinp-spring-cloud 代码在 flowable-demo 包,IDEA Active profiles 配置为 sit 测试分支,单独启动即可

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143172.html原文链接:https://javaforall.cn



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3