文章目录
flowable GitHub仓库:
https://github.com/flowable/flowable-engine
下载源码,或者git clone
找到 modules/flowable-ui-modeler/flowable-ui-modeler-app
模块,拷贝该模块下resource/static/目录下的所有内容至自己项目的resource/static/目录下。
注意:一定要注意源码版本要与项目中的flowable一致,否则会有资源文件获取不到
这里我复制到了 static/modeler/ 目录下
然后启动项目,访问其中的index页面:
http://localhost:10001/modeler/index.html(根据情况修改访问路径)
官方提供首页:
发现少了点东西,f12检查
与官方对比下发现,路径中多了静态资源目录 modeler
我们找到static/modeler/scripts/app-cfg.js
这个文件,做下修改
FLOWABLE.CONFIG = {
'onPremise' : true,
'contextRoot' : "",
'webContextRoot' : "",
'datesLocalization' : false
};
重启访问index.html
路径是对了,但是还是404错误,account请求是获取登录用户信息的,我们可以实现这个请求,返回一个内置用户,去除登录逻辑;
在项目中全局查找/app/rest/account
,在static/modeler/scripts/configuration/url-config.js
文件中定义的,我们将请求路径修改一下
参考官方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\"]}";
}
}
重启再访问
这时虽然页面看起来没有问题,但是一些操作还是无法完成的,再看一下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>
重启访问,发现需要登录
Flowable Security自动配置类org.flowable.spring.boot.FlowableSecurityAutoConfiguration
,其在org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
配置前完成自动配置
因此只要排除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
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
FlowableCommonAppProperties中的这三个属性是没有配置,那就配置一下呗application.properties
# 随便配置,不会用到
flowable.common.app.idm-url=a
flowable.common.app.idm-admin.user=a
flowable.common.app.idm-admin.password=a
重启访问,又报错了(点根烟继续)
mybatis mapper 映射文件找不到
新建一个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}
将这两个属性在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中
写一个类来生成表
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
查看数据库,表已生成
重启访问,创建模型,保存时报错
获取不到当前用户的id
那定义一个拦截器,拦截以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);
}
}
重启访问,创建模型,终于成功了
查看数据库
保存模型,也成功
OK,真不容易