Flowable Modeler集成
文章目录
Flowable 简介
flowable 和activiti类似也是一个流程引擎,是activiti原班人马从activiti离职后,到另一家公司重新开发的一套流程引擎,其从activiti6拉出一个分支进行修改。
这里是Flowable的官方地址:点我
这里是Flowable的官方github地址:点我
这里是Flowable的gitee地址:点我
Flowable 设计器集成
1. 添加Flowable相关依赖
主要是:liquibase、flowable-spring-boot-starter-process、flowable-ui-modeler-rest,其他是数据库连接所必要的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
<version>6.6.0</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-rest</artifactId>
<version>6.6.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>
2. 添加配置文件及配置类
添加配置文件:
server.port=9999
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8&serverTimezone=UTC&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
添加配置类,主要是设置数据源和整合flowable的自定义引擎配置类SpringProcessEngineConfiguration,这样在启动项目后会自动为我们创建好flowable所需的数据库。
/**
* @program: flowable-ui
* @author: Mr.Lemon
* @create: 2020/11/18 22:55
**/
@Configuration
public class FlowableProcessEngine {
@Autowired
private DataSource dataSource;
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(){
SpringProcessEngineConfiguration springProcessEngineConfiguration = new SpringProcessEngineConfiguration();
springProcessEngineConfiguration.setDataSource(dataSource);
springProcessEngineConfiguration.setDatabaseSchemaUpdate("true");
springProcessEngineConfiguration.setTransactionManager(dataSourceTransactionManager(dataSource));
return springProcessEngineConfiguration;
}
}
这里在配置的时候遇到了一个问题(这里截取关键的一小段):
Caused by: org.flowable.common.engine.api.FlowableException: couldn't upgrade db schema: insert into ACT_GE_PROPERTY values ('common.schema.version', '6.2.0.0', 1)
at org.flowable.common.engine.impl.db.AbstractSqlScriptBasedDbSchemaManager.executeSchemaResource(AbstractSqlScriptBasedDbSchemaManager.java:343) ~[flowable-engine-common-6.6.0.jar:6.6.0]
at org.flowable.common.engine.impl.db.AbstractSqlScriptBasedDbSchemaManager.executeSchemaResource(AbstractSqlScriptBasedDbSchemaManager.java:227) ~[flowable-engine-common-6.6.0.jar:6.6.0]
at org.flowable.common.engine.impl.db.AbstractSqlScriptBasedDbSchemaManager.dbSchemaUpgrade(AbstractSqlScriptBasedDbSchemaManager.java:98) ~[flowable-engine-common-6.6.0.jar:6.6.0]
at org.flowable.common.engine.impl.db.ServiceSqlScriptBasedDbSchemaManager.schemaUpdate(ServiceSqlScriptBasedDbSchemaManager.java:78) ~[flowable-engine-common-6.6.0.jar:6.6.0]
at org.flowable.eventregistry.impl.db.EventDbSchemaManager.schemaUpdate(EventDbSchemaManager.java:62) ~[flowable-event-registry-6.6.0.jar:6.6.0]
at org.flowable.common.engine.impl.db.LiquibaseBasedSchemaManager.initSchema(LiquibaseBasedSchemaManager.java:61) ~[flowable-engine-common-6.6.0.jar:6.6.0]
... 55 common frames omitted
Caused by: java.sql.SQLSyntaxErrorException: Table 'flowable.act_ge_property' doesn't exist
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.22.jar:8.0.22]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.22.jar:8.0.22]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.22.jar:8.0.22]
at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:764) ~[mysql-connector-java-8.0.22.jar:8.0.22]
at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648) ~[mysql-connector-java-8.0.22.jar:8.0.22]
at com.alibaba.druid.pool.DruidPooledStatement.execute(DruidPooledStatement.java:632) ~[druid-1.2.3.jar:1.2.3]
at org.flowable.common.engine.impl.db.AbstractSqlScriptBasedDbSchemaManager.executeSchemaResource(AbstractSqlScriptBasedDbSchemaManager.java:314) ~[flowable-engine-common-6.6.0.jar:6.6.0]
... 60 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:9146', transport: 'socket'
Process finished with exit code 1
如何解决那?在mysql的连接字符串中添加上nullCatalogMeansCurrent=true,将schema默认设置为当前连接的schema。再次启动,表创建完毕。
参考:https://blog.csdn.net/houyj1986/article/details/85546680
3. 拷贝静态文件
我从官方github上clone了源代码,直接从源代码中获取静态文件(记得切换你maven中的版本的分支去获取),获取的项目路径为:modules\flowable-ui\flowable-ui-modeler-frontend\src\main\resources\static\modeler。将静态文件拷贝到我们所创建的static目录下即可。
当然你也可以去官方github下载war包,从war包中获取静态文件。
4. 启动时报错解决
引入静态文件后,启动项目,可以看到静态页面了,但是还是有问题,不同版本的遇到的问题可能不同,我列出我所遇到的问题。
- app/rest/account 接口404错误
- /rest/models 接口500错误
account接口404问题
针对问题一,很明显是缺少对应的接口,我们可以从源项目中查询下:
对应方法:org.flowable.ui.common.rest.idm.remote.RemoteAccountResource#getAccount
/**
* GET /rest/account -> get the current user.
*/
@GetMapping(value = "/rest/account", produces = "application/json")
public UserRepresentation getAccount(Authentication authentication) {
UserRepresentation userRepresentation = null;
for (CurrentUserProvider userProvider : currentUserProviders) {
if (userProvider.supports(authentication)) {
userRepresentation = userProvider.getCurrentUser(authentication);
}
if (userRepresentation != null) {
break;
}
}
if (userRepresentation == null) {
userRepresentation = getCurrentUserRepresentation(authentication.getName());
}
if (userRepresentation != null) {
return userRepresentation;
} else {
throw new NotFoundException();
}
}
不能看出,这个接口返回了一个用户信息,那么我们没必要说一定要返回真的数据,我们可以mock一个数据,所以改动下接口(这里怕和源码原接口冲突,我改了下接口地址,可以全局搜下原接口替换为我们修改后的接口即可):
/**
* @program: flowable-ui
* @author: Mr.Lemon
* @create: 2020/11/19 23:00
**/
@RestController()
@RequestMapping("/my-app")
public class MyRemoteAccountController {
protected final Collection<CurrentUserProvider> currentUserProviders;
public MyRemoteAccountController(ObjectProvider<CurrentUserProvider> currentUserProviders) {
this.currentUserProviders = currentUserProviders.orderedStream().collect(Collectors.toList());
}
/**
* GET /rest/account -> get the current user.
*/
@GetMapping(value = "/rest/account", produces = "application/json")
public UserRepresentation getAccount(Authentication authentication) {
UserRepresentation userRepresentation = new UserRepresentation();
userRepresentation.setId("lemon");
userRepresentation.setFirstName("lemon");
userRepresentation.setPrivileges(Lists.newArrayList("flowable-idm","flowable-modeler","flowable-task"));
return userRepresentation;
}
}
/rest/models 接口500问题
这里贴出关键错误信息:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for org.flowable.ui.modeler.domain.Model.selectModelByParameters
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for org.flowable.ui.modeler.domain.Model.selectModelByParameters] with root cause
java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for org.flowable.ui.modeler.domain.Model.selectModelByParameters
at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:1009) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:799) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:792) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:146) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~[mybatis-3.5.5.jar:3.5.5]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~[mybatis-spring-2.0.5.jar:2.0.5]
at com.sun.proxy.$Proxy62.selectList(Unknown Source) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223) ~[mybatis-spring-2.0.5.jar:2.0.5]
at org.flowable.ui.modeler.repository.ModelRepositoryImpl.findModelsByParameters(ModelRepositoryImpl.java:88) ~[flowable-ui-modeler-logic-6.6.0.jar:6.6.0]
at org.flowable.ui.modeler.repository.ModelRepositoryImpl.findByModelType(ModelRepositoryImpl.java:52) ~[flowable-ui-modeler-logic-6.6.0.jar:6.6.0]
at org.flowable.ui.modeler.service.FlowableModelQueryService.getModels(FlowableModelQueryService.java:118) ~[flowable-ui-modeler-logic-6.6.0.jar:6.6.0]
at org.flowable.ui.modeler.service.FlowableModelQueryService$$FastClassBySpringCGLIB$$5d5205bf.invoke(<generated>) ~[flowable-ui-modeler-logic-6.6.0.jar:6.6.0]
从报错信息中很容易看出,是我mybatis配置出了问题,看下我的配置:
server.port=9999
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8&serverTimezone=UTC&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath*:mapping/*Mapper.xml
flowable.common.app.idm-url=127.0.0.1:9999/
flowable.common.app.idm-admin.user=admin
flowable.common.app.idm-admin.password=test
flowable.common.app.idm-redirect-url=http://127.0.0.1:9999
很显然是 mybatis.mapper-locations 少配了flowable的mapper.xml所在文件地址,配上即可:
server.port=9999
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8&serverTimezone=UTC&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath*:mapping/*Mapper.xml,META-INF/modeler-mybatis-mappings/*.xml
flowable.common.app.idm-url=127.0.0.1:9999/
flowable.common.app.idm-admin.user=admin
flowable.common.app.idm-admin.password=test
flowable.common.app.idm-redirect-url=http://127.0.0.1:9999
其他错误
再次启动,发现还是报错:
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'class path resource [META-INF/modeler-mybatis-mappings/Model.xml]'. Cause: org.apache.ibatis.builder.BuilderException: Error resolving JdbcType. Cause: java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.type.JdbcType.${blobType}
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:123) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:95) ~[mybatis-3.5.5.jar:3.5.5]
at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:610) ~[mybatis-spring-2.0.5.jar:2.0.5]
... 113 common frames omitted
Caused by: org.apache.ibatis.builder.BuilderException: Error resolving JdbcType. Cause: java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.type.JdbcType.${blobType}
at org.apache.ibatis.builder.BaseBuilder.resolveJdbcType(BaseBuilder.java:73) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildResultMappingFromContext(XMLMapperBuilder.java:392) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:280) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:254) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:246) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:119) ~[mybatis-3.5.5.jar:3.5.5]
... 115 common frames omitted
Caused by: java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.type.JdbcType.${blobType}
at java.lang.Enum.valueOf(Enum.java:238) ~[na:1.8.0_191]
at org.apache.ibatis.type.JdbcType.valueOf(JdbcType.java:25) ~[mybatis-3.5.5.jar:3.5.5]
at org.apache.ibatis.builder.BaseBuilder.resolveJdbcType(BaseBuilder.java:71) ~[mybatis-3.5.5.jar:3.5.5]
... 120 common frames omitted
关键错误:No enum constant org.apache.ibatis.type.JdbcType.${blobType},找到 Model.xml
这里用了动态的jdbcType
<result property="thumbnail" column="thumbnail" jdbcType="${blobType}" />
需要在配置文件里加个配置
mybatis.configuration-properties.blobType=BLOB
这时候又报了个错:
java.sql.SQLSyntaxErrorException: Table 'flowable.act_de_model' doesn't exist
怎么解决那,其实就是初始化的时候没生成对应的数据库,从源码拷贝以下代码到项目中,运行即可:
/**
* @program: flowable-ui
* @author: Mr.Lemon
* @create: 2020/11/24 23:59
**/
@Configuration
public class DataBaseConfig {
protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";
@Bean
@Qualifier("flowableModeler")
public Liquibase modelerLiquibase(DataSource dataSource) throws SQLException, LiquibaseException {
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 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) {
}
}
}
}
}
这时候可以看到我们的项目成型了:
点击创建BPMN的时候又报错了。。。,来看下是报的什么错
There is no getter for property named 'prefix' in 'class org.flowable.ui.modeler.domain.Model'
看情况是配置少了,添加如下配置即可(可以不赋值):
mybatis.configuration-properties.prefix=
配置完后,启动项目,创建BPMN,OK,完成!
总结
不同的版本可能遇到的问题不同,如果遇到不同的错误,看下控制台的错误研究下错误对应的源码一点点的去修改,很快就能解决