SpringBoot集成Flowable modeler设计器

文章目录

SpringBoot整合Flowable

flowable GitHub仓库:
https://github.com/flowable/flowable-engine

下载源码,或者git clone

找到 modules/flowable-ui-modeler/flowable-ui-modeler-app 模块,拷贝该模块下resource/static/目录下的所有内容至自己项目的resource/static/目录下。

注意:一定要注意源码版本要与项目中的flowable一致,否则会有资源文件获取不到

SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
这里我复制到了 static/modeler/ 目录下

然后启动项目,访问其中的index页面:
http://localhost:10001/modeler/index.html(根据情况修改访问路径)

SpringBoot集成Flowable modeler设计器

官方提供首页:
SpringBoot集成Flowable modeler设计器
发现少了点东西,f12检查
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器

与官方对比下发现,路径中多了静态资源目录 modeler
SpringBoot集成Flowable modeler设计器
我们找到static/modeler/scripts/app-cfg.js 这个文件,做下修改

FLOWABLE.CONFIG = {
	'onPremise' : true,
	'contextRoot' : "",
	'webContextRoot' : "",
	'datesLocalization' : false
};

重启访问index.html
SpringBoot集成Flowable modeler设计器
路径是对了,但是还是404错误,account请求是获取登录用户信息的,我们可以实现这个请求,返回一个内置用户,去除登录逻辑;

在项目中全局查找/app/rest/account,在static/modeler/scripts/configuration/url-config.js文件中定义的,我们将请求路径修改一下
SpringBoot集成Flowable modeler设计器
参考官方modeler的响应

SpringBoot集成Flowable modeler设计器

@RestController
@RequestMapping("/modeler/app")
public class AppRestResource {

    @GetMapping("/rest/account")
    public String getAccount() {
        // 参考官方提供的响应数据
        return "{\"id\":\"admin\",\"firstName\":\"Test\",\"lastName\":\"Administrator\",\"email\":\"admin@flowable.org\",\"fullName\":\"Test Administrator\",\"groups\":[],\"privileges\":[\"access-idm\",\"access-rest-api\",\"access-task\",\"access-modeler\",\"access-admin\"]}";
    }
}

重启再访问

SpringBoot集成Flowable modeler设计器
这时虽然页面看起来没有问题,但是一些操作还是无法完成的,再看一下static/modeler/scripts/configuration/url-config.js这个文件,其中有很多请求服务端都没有实现的;两种方法:1、参考源码一个个自己实现;2、引入这些请求的源码包

很显然,选择第二种方式,引入源码包

<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-ui-modeler-rest</artifactId>
    <version>${flowable.version}</version>
</dependency>

重启访问,发现需要登录
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
Flowable Security自动配置类org.flowable.spring.boot.FlowableSecurityAutoConfiguration,其在org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration配置前完成自动配置
SpringBoot集成Flowable modeler设计器
因此只要排除SecurityAutoConfiguration的自动配置,Flowable Security就不会被配置。在启动类@SpringBootApplication中排除SecurityAutoConfiguration

@SpringBootApplication(
        exclude = {SecurityAutoConfiguration.class}
)

重启访问,发现没有了登陆认证,但是其他操作还是无法操作(http请求404),虽然我们引入了请求源码包,但是SpringBoot并没有扫描这些包

@ComponentScan(basePackages = {
        "org.flowable.ui",
        "top.theonly.flowable.springboot"
})

重启,报错了(日了狗了)

Description:

Parameter 1 of constructor in org.flowable.ui.modeler.service.AppDefinitionPublishService required a bean of type 'org.flowable.ui.modeler.properties.FlowableModelerAppProperties' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.flowable.ui.modeler.properties.FlowableModelerAppProperties' in your configuration.

在AppDefinitionPublishService中,没有找到类型为FlowableModelerAppProperties的bean

SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
FlowableModelerAppProperties没有交给Spring容器管理。

我们可以定义个类继承FlowableModelerAppProperties,交给Spring容器管理。

@Component
public class CustomFlowableModelerAppProperties extends FlowableModelerAppProperties {
}

重启,又又报错了

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'editorGroupsResource': Unsatisfied dependency expressed through field 'remoteIdmService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'remoteIdmServiceImpl' defined in URL [jar:file:/C:/DevTools/Maven/repository/org/flowable/flowable-ui-common/6.4.2/flowable-ui-common-6.4.2.jar!/org/flowable/ui/common/service/idm/RemoteIdmServiceImpl.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flowable.ui.common.service.idm.RemoteIdmServiceImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: `flowable.common.app.idm-url` must be set
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:598) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1402) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:863) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE]
	at top.theonly.flowable.springboot.FlowableSpringBootApplication.main(FlowableSpringBootApplication.java:19) [classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_241]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_241]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_241]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_241]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.16.RELEASE.jar:2.1.16.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'remoteIdmServiceImpl' defined in URL [jar:file:/C:/DevTools/Maven/repository/org/flowable/flowable-ui-common/6.4.2/flowable-ui-common-6.4.2.jar!/org/flowable/ui/common/service/idm/RemoteIdmServiceImpl.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flowable.ui.common.service.idm.RemoteIdmServiceImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: `flowable.common.app.idm-url` must be set
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:304) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1193) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	... 24 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flowable.ui.common.service.idm.RemoteIdmServiceImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: `flowable.common.app.idm-url` must be set
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	... 37 common frames omitted
Caused by: java.lang.IllegalArgumentException: `flowable.common.app.idm-url` must be set
	at org.springframework.util.Assert.hasText(Assert.java:284) ~[spring-core-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	at org.flowable.ui.common.properties.FlowableCommonAppProperties.determineIdmAppUrl(FlowableCommonAppProperties.java:135) ~[flowable-ui-common-6.4.2.jar:6.4.2]
	at org.flowable.ui.common.service.idm.RemoteIdmServiceImpl.<init>(RemoteIdmServiceImpl.java:59) ~[flowable-ui-common-6.4.2.jar:6.4.2]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_241]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_241]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_241]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_241]
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE]
	... 39 common frames omitted

SpringBoot集成Flowable modeler设计器
FlowableCommonAppProperties中的这三个属性是没有配置,那就配置一下呗
application.properties

# 随便配置,不会用到
flowable.common.app.idm-url=a
flowable.common.app.idm-admin.user=a
flowable.common.app.idm-admin.password=a

重启访问,又报错了(点根烟继续)
SpringBoot集成Flowable modeler设计器
mybatis mapper 映射文件找不到
SpringBoot集成Flowable modeler设计器
新建一个mybatis配置文件mybatis-cfg.xml,将上面三个映射文件添加进来

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <mappers>
        <mapper resource="META-INF/modeler-mybatis-mappings/Model.xml"/>
        <mapper resource="META-INF/modeler-mybatis-mappings/ModelHistory.xml"/>
        <mapper resource="META-INF/modeler-mybatis-mappings/ModelRelation.xml"/>
    </mappers>
</configuration>

配置mybatis配置文件位置

mybatis.config-location=classpath:mybatis/mybatis-cfg.xml

重启,又又又又报错

Caused by: java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.type.JdbcType.${blobType}

SpringBoot集成Flowable modeler设计器
将这两个属性在mybatis配置文件中配置一下

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties>
        <property name="prefix" value=""/>
        <property name="blobType" value="BLOB"/>
    </properties>
    <mappers>
        <mapper resource="META-INF/modeler-mybatis-mappings/Model.xml"/>
        <mapper resource="META-INF/modeler-mybatis-mappings/ModelHistory.xml"/>
        <mapper resource="META-INF/modeler-mybatis-mappings/ModelRelation.xml"/>
    </mappers>
</configuration>

重启访问,后台又又又又又报错

### Cause: java.sql.SQLSyntaxErrorException: Table 'flowable-springboot2.act_de_model' doesn't exist
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Table 'flowable-springboot2.act_de_model' doesn't exist] with root cause

act_de_model表不存在

使用liquibase生成表

引入依赖

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
    <version>3.6.3</version>
</dependency>

copy flowable-modeler-app-db-changelog.xml到自己项目resource中
SpringBoot集成Flowable modeler设计器
写一个类来生成表

public class FlowableLiquibaseTest {
    public static void main(String[] args) throws SQLException, LiquibaseException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/flowable-springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");

        DruidPooledConnection connection = dataSource.getConnection();

        DatabaseConnection databaseConnection = new JdbcConnection(connection);
        Database db = DatabaseFactory.getInstance()
                .findCorrectDatabaseImplementation(databaseConnection);

        Liquibase liquibase = new Liquibase("liquibase/flowable-modeler-app-db-changelog.xml",
                new ClassLoaderResourceAccessor(), db);

        liquibase.update("flowable");
    }
}

运行main方法

11:13:08.790 [main] INFO liquibase.lockservice.StandardLockService - Successfully released change log lock

查看数据库,表已生成
SpringBoot集成Flowable modeler设计器
重启访问,创建模型,保存时报错
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
获取不到当前用户的id
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器
那定义一个拦截器,拦截以app开头的路径,设置一个user

public class CustomHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String servletPath = request.getServletPath();
        if (servletPath.startsWith("/app")) {
            User user = new UserEntityImpl();
            user.setId("admin");
            SecurityUtils.assumeUser(user);
        }
        return true;
    }

}

添加拦截器

@Configuration
public class CustomInterceptorAdapter extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomHandlerInterceptor())
                .addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

重启访问,创建模型,终于成功了
SpringBoot集成Flowable modeler设计器
查看数据库
SpringBoot集成Flowable modeler设计器
保存模型,也成功
SpringBoot集成Flowable modeler设计器
SpringBoot集成Flowable modeler设计器

OK,真不容易

上一篇:3D重建传统算法对比深度学习,SFU谭平:更需要的是二者的融合


下一篇:转载:Spring Bean的生命周期