我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringBoot 集成Flowable设计器(Flowable-ui)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringBoot 集成Flowable设计器(Flowable-ui)

一、项目场景:

提示:使用版本6.7.0

公司使用前后端项目分离,前端使用bpmn插件生成bpmn xml文件,后端解析处理数据。今天主要介绍后端集成flowable设计器的过程中遇到的问题。
如需了解flowable框架集成请参考文档
Flowable BPMN 用户手册 (v 6.3.0)


二、集成过程

提示:项目中遇到的问题:
为什么需要自己集成Flowable设计器?因为SpringBoot提供的依赖只集成Flowable引擎模块,没有集成modeler模块。SpringBoot集成Flowable需要导入如下依赖:

                            org.flowable            flowable-spring-boot-starter-process            ${flowable.version}        


可以看到没有集成和modeler相关的依赖,如下是flowable源码中提供的流程设计器模块:
flowable-ui-modeler-conf: 放置一些列的配置项
flowable-ui-modeler-frontend: 前端
flowable-ui-modeler-logic: 放置Service以及dao层
flowable-ui-modeler-rest: 放置Controller层
因为只需要集成flowable操作model 接口相关组件,所以只需要集成logic模块即可,添加依赖如下:

                            org.flowable            flowable-ui-modeler-logic            ${flowable.version}        

三、问题总结:

提示:这里填写问题的分析:

1、程序启动报错(flowable.common.app.idm-url must be set)

`Failed to instantiate [org.flowable.ui.common.service.idm.RemoteIdmService]: Factory method 'remoteIdmService' threw exception; nested exception is java.lang.IllegalArgumentException: `flowable.common.app.idm-url` must be set`

这个是由于flowable调用自己的用户权限导致的,如果把flowable集成自己的框架里面,就不需要用它自带的用户体现和权限了。

解决方案:将FlowableUiSecurityAutoConfiguration排除

@SpringBootApplication(exclude = {FlowableUiSecurityAutoConfiguration.class})

2、引入modelService报红,运行报错

Field modelService in com.nmb.zx.base.sys.flow.service.FlowModelInfoService required a bean of type 'org.flowable.ui.modeler.serviceapi.ModelService' that could not be found.

解决方案:参考flowable flowable-ui-modeler-conf组件中的源码中的配置类扫描我们需要的注入的类所在的包即可:
添加ModelerBeanConfig.java配置类到项目任意位置:

import org.flowable.ui.common.properties.FlowableCommonAppProperties;import org.flowable.ui.modeler.repository.ModelRepositoryImpl;import org.flowable.ui.modeler.service.FlowableModelQueryService;import org.flowable.ui.modeler.service.ModelImageService;import org.flowable.ui.modeler.service.ModelServiceImpl;import org.flowable.ui.modeler.serviceapi.ModelService;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;@Configuration@ComponentScan(value = {//       "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 = {        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ModelRepositoryImpl.class)})@EnableConfigurationProperties({FlowableCommonAppProperties.class})public class ModelerBeanConfig {    @Bean    public ModelService createModelService() {        return new ModelServiceImpl();    }    @Bean    public ModelImageService createModelImageService() {        return new ModelImageService();    }    @Bean    public FlowableModelQueryService createFlowableModelQueryService() {        return new FlowableModelQueryService();    }}

mybatisPlus中添加配置
在这里插入图片描述添加BPMN配置文件FlowBpmnConfig

import com.fasterxml.jackson.databind.ObjectMapper;import com.nmb.zx.base.core.config.flow.customcache.CustomDeploymentCache;import com.nmb.zx.base.core.config.flow.customcache.CustomProcessDefinitionInfoCache;import org.apache.ibatis.session.SqlSessionFactory;import org.flowable.bpmn.converter.BpmnXMLConverter;import org.flowable.spring.SpringProcessEngineConfiguration;import org.flowable.spring.boot.EngineConfigurationConfigurer;import org.flowable.validation.ProcessValidatorFactory;import org.mybatis.spring.SqlSessionTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;@Configurationpublic class FlowBpmnConfig implements EngineConfigurationConfigurer {    @Autowired    private CustomDeploymentCache customDeploymentCache;    @Autowired    private CustomProcessDefinitionInfoCache customProcessDefinitionInfoCache;    @Override    public void configure(SpringProcessEngineConfiguration configuration) {        configuration.setEnableProcessDefinitionInfoCache(true);        configuration.setProcessDefinitionCache(customDeploymentCache);        configuration.setProcessDefinitionInfoCache(customProcessDefinitionInfoCache);        //设置自定义的uuid生成策略        configuration.setIdGenerator(uuidGenerator());    }    @Bean    public ProcessValidatorFactory processValidator(){        return new ProcessValidatorFactory();    }    @Bean    public ObjectMapper objectMapper() {        return new ObjectMapper();    }    @Bean    public UuidGenerator uuidGenerator() {        return new UuidGenerator();    }        @Bean    public BpmnXMLConverter createBpmnXMLConverter() {        return new BpmnXMLConverter();    }        @Bean    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();        configurer.setIgnoreUnresolvablePlaceholders(true);        return configurer;    }    @Bean(destroyMethod = "clearCache")    @Qualifier("flowableModeler")    public SqlSessionTemplate modelerSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory);    }}
import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;public class UuidGenerator extends StrongUuidGenerator {    @Override    public String getNextId() {        String uuid = super.getNextId();        uuid = uuid.replaceAll("-", "");        return uuid;    }}
import org.flowable.common.engine.impl.persistence.deploy.DeploymentCache;import org.flowable.engine.impl.persistence.deploy.ProcessDefinitionCacheEntry;import org.flowable.engine.repository.ProcessDefinition;import org.springframework.stereotype.Component;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;@Componentpublic class CustomDeploymentCache implements DeploymentCache {    protected String id;    protected ProcessDefinitionCacheEntry entry;    @Override    public ProcessDefinitionCacheEntry get(String id) {        if (id.equals(this.id)) {            return entry;        }        return null;    }    @Override    public void add(String id, ProcessDefinitionCacheEntry object) {        this.id = id;        this.entry = object;    }    @Override    public void remove(String id) {        if (id.equals(this.id)) {            this.id = null;            this.entry = null;        }    }    @Override    public void clear() {        this.id = null;        this.entry = null;    }    @Override    public boolean contains(String id) {        return id.equals(this.id);    }    @Override    public Collection getAll() {        if (entry != null) {            return Collections.singletonList(entry);        } else {            return new ArrayList<>();        }    }    @Override    public int size() {        if (entry != null) {            return 1;        } else {            return 0;        }    }    // For testing purposes only    public ProcessDefinition getCachedProcessDefinition() {        if (entry == null) {            return null;        }        return entry.getProcessDefinition();    }}
import org.flowable.common.engine.impl.persistence.deploy.DeploymentCache;import org.flowable.engine.impl.persistence.deploy.ProcessDefinitionInfoCacheObject;import org.springframework.stereotype.Component;import java.util.Collection;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;@Componentpublic class CustomProcessDefinitionInfoCache implements DeploymentCache {    private final Map cache = new ConcurrentHashMap<>();    @Override    public ProcessDefinitionInfoCacheObject get(String id) {        return cache.get(id);    }    @Override    public boolean contains(String id) {        return cache.containsKey(id);    }    @Override    public void add(String id, ProcessDefinitionInfoCacheObject object) {        cache.put(id, object);    }    @Override    public void remove(String id) {        cache.remove(id);    }    @Override    public void clear() {        cache.clear();    }    @Override    public Collection getAll() {        return cache.values();    }    @Override    public int size(){        return cache.size();    }}

3、启动后访问接口直接重定向到登录页面

在这里插入图片描述

import org.flowable.ui.common.security.SecurityConstants;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;@Configuration(proxyBeanMethods = false)@EnableWebSecuritypublic class ModelerSecurityConfiguration {    @Configuration    @Order(SecurityConstants.MODELER_API_SECURITY_ORDER)    public static class ModelerApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {        @Override        protected void configure(HttpSecurity http) throws Exception {            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();            successHandler.setTargetUrlParameter("redirectTo");            http.headers().frameOptions().disable();            http.csrf().disable().authorizeRequests().antMatchers("**").permitAll().anyRequest().authenticated().and().httpBasic();        }    }}

4、运行成功请求接口

找不到act_de_model表,因为flowable将act_re_model改成了act_de_model表了,所以需要手动添加配置类生产act_de_model表:

import liquibase.Liquibase;import liquibase.database.Database;import liquibase.database.DatabaseConnection;import liquibase.database.DatabaseFactory;import liquibase.database.jvm.JdbcConnection;import liquibase.exception.DatabaseException;import liquibase.resource.ClassLoaderResourceAccessor;import org.flowable.ui.common.service.exception.InternalServerErrorException;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class DatabaseConfiguration {    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DatabaseConfiguration.class);    protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";    @Bean    public Liquibase liquibase(DataSource dataSource) {        LOGGER.info("Configuring Liquibase");        Liquibase liquibase = null;        try {            DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());            Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);            database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName());            database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName());            liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);            liquibase.update("flowable");            return liquibase;        } catch (Exception e) {            throw new InternalServerErrorException("Error creating liquibase database", e);        } finally {            closeDatabase(liquibase);        }    }        private void closeDatabase(Liquibase liquibase) {        if (liquibase != null) {            Database database = liquibase.getDatabase();            if (database != null) {                try {                    database.close();                } catch (DatabaseException e) {                    LOGGER.warn("Error closing database", e);                }            }        }    }}

来源地址:https://blog.csdn.net/weixin_37304961/article/details/129255799

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringBoot 集成Flowable设计器(Flowable-ui)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringBoot 集成Flowable设计器(Flowable-ui)

一、项目场景: 提示:使用版本6.7.0 公司使用前后端项目分离,前端使用bpmn插件生成bpmn xml文件,后端解析处理数据。今天主要介绍后端集成flowable设计器的过程中遇到的问题。 如需了解flowable框架集成请参考文
2023-08-16

springBoot集成flowable的流程解析

这篇文章主要介绍了springBoot集成flowable的流程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-02-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录