1. Introduction
1.1. 翻译(说明)
由[分享牛Flowable中国社区] 翻译,任何意见建议,欢迎联系QQ:3152981878。 如果想一起成为开源代码贡献人员,欢迎大家加入qq交流群为社区贡献添砖加瓦。qq贡献群:1023773998
1.2. 协议
Flowable在Apache V2 协议下发布。
1.4. 源码
Flowable的发布包里包含了大部分源码,以JAR文件方式提供。Flowable的源码也可以通过以下链接获得: https://github.com/flowable/flowable-engine
1.5. 必要的软件
1.5.1. JDK 8+
运行Flowable需要JDK 8或以上版本。可以访问 Oracle Java SE downloads页面 点击“Download JDK”按钮获取。该页面上也有安装指导。安装完成后,可以执行 java -version 。能看到JDK的版本信息就说明安装成功了。
1.5.2. IDE
可以自行选择用于Flowable开发的IDE。如果想要使用Flowable Designer,则需要Eclipse Mars或Neon。
到 Eclipse下载页面选择Eclipse版本并下载。解压下载的文件,
然后执行eclipse文件夹下的eclipse文件。手册后续有专门一章介绍如何安装我们的Eclipse Designer插件。
1.7. 实验性功能
标记有[实验性]的章节介绍的功能还不够稳定。
.impl.包下的类都是内部实现类,不保证稳定。但是,在用户手册中作为配置参数介绍的类则是被官方支持的,可以保证稳定。
1.8. 内部实现类
在JAR文件中,所有.impl.包下的类(比如org.flowable.engine.impl.db)都是实现类,只应在内部使用。实现类中的所有类或接口都不保证稳定。
1.9. 版本策略
使用三个整数的形式标记版本:MAJOR.MINOR.MICRO。其中 MAJOR版本代表核心引擎的演进。MINOR版本代表新功能与新API。MICRO版本代表bug修复与改进。
总的来说,Flowable希望在MINOR与MICRO版本中,对所有非内部实现类保持“源代码兼容性”,即应用可以正确构建,且不改变语义。Flowable也希望在MINOR与MICRO版本中,保持“二进制兼容性”,即用新版本的Flowable直接替换老版本的Jar文件,仍然可以正常工作。
如果在MINOR版本中修改了API,将保留原有版本,并使用@Deprecated注解。这种废弃的API将在两个MINOR版本之后移除。
2. 配置
2.1. 创建表单引擎
Flowable 表单引擎的结构与Flowable流程引擎非常相似。 因此,文档的某些部分与其流程引擎对应部分相似.
Flowable Form引擎通过名为flowable.form.cfg.xml的XML文件进行配置。 请注意,如果您使用的是“springintegration,构建表单引擎的Spring样式”,则这不适用*。
获取FormEngine的最简单方法是使用org.flowable.form.engine.FormEngines类:
1FormEngine formEngine = FormEngines.getDefaultFormEngine()
这将在类路径上查找flowable.form.cfg.xml文件,并根据该文件中的配置构造引擎。 以下代码段显示了示例配置。 以下部分将详细介绍配置属性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="formEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneFormEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
请注意,配置XML实际上是Spring配置。 这并不意味着Flowable Form只能在Spring环境中使用! 我们只是在内部利用Spring的解析和依赖注入功能来构建引擎。
也可以使用配置文件以编程方式创建FormEngineConfiguration对象。 也可以使用不同的bean id(例如,参见第3行)。
1
2
3
4
5
6
FormEngineConfiguration.
createFormEngineConfigurationFromResourceDefault();
createFormEngineConfigurationFromResource(String resource);
createFormEngineConfigurationFromResource(String resource, String beanName);
createFormEngineConfigurationFromInputStream(InputStream inputStream);
createFormEngineConfigurationFromInputStream(InputStream inputStream, String beanName);
也可以不使用配置文件,并基于创建配置 默认值(有关更多信息,请参阅<< configurationClasses类>>)。
1
2
FormEngineConfiguration.createStandaloneFormEngineConfiguration();
FormEngineConfiguration.createStandaloneInMemFormEngineConfiguration();
所有这些FormEngineConfiguration.createXXX()方法返回一个FormEngineConfiguration,如果需要可以进一步调整。 调用buildFormEngine()操作后,创建一个FormEngine:
1
2
3
4
FormEngine formEngine = FormEngineConfiguration.createStandaloneInMemFormEngineConfiguration()
.setDatabaseSchemaUpdate(FormEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
.setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
.buildFormEngine();
2.2. 表单引擎配置类
flowable.form.cfg.xml文件必须包含一个具有id值为 formEngineConfiguration 的bean。
1 <bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
然后使用该bean构造FormEngine。
-
org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration: the process engine is used in a standalone way. Flowable will take care of the transactions. By default, the database will only be checked when the engine boots (and an exception is thrown if there is no Flowable Form schema or the schema version is incorrect).
-
org.flowable.form.engine.impl.cfg.StandaloneInMemFormEngineConfiguration: this is a convenience class for unit testing purposes. Flowable Form will take care of the transactions. An H2 in-memory database is used by default. The database will be created and dropped when the engine boots and shuts down. When using this, probably no additional configuration is needed).
-
org.flowable.form.spring.SpringFormEngineConfiguration: To be used when the Form engine is used in a Spring environment. See the Spring integration section for more information.
2.3. 插件方式集成流程引擎
除了在独立模式下运行外,还可以将表单引擎插入流程引擎。 这使得流程引擎可以识别它和其他引擎。 例如,这可以将包含BPMN模型和DMN模型的工件部署到流程引擎的部署服务API。
要使流程引擎知道表单引擎,需要将org.flowable.dmn.engine.configurator.FormEngineConfigurator添加到流程引擎配置中的配置程序列表中。 此配置程序是flowable-form-engine-configurator模块的一部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="configurators">
<list>
<ref bean="formEngineConfigurator" />
</list>
</property>
...
</bean>
<bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
</bean>
<bean id="formEngineConfigurator" class="org.flowable.form.engine.configurator.FormEngineConfigurator">
<property name="formEngineConfiguration" ref="formEngineConfiguration" />
</bean>
2.4. 数据源配置
有两种方法可以配置Flowable 表单引擎将使用的数据库。 第一个选项是定义数据库的JDBC属性: * jdbcUrl: 数据库的JDBC URL. * jdbcDriver: 为特定数据库类型实现驱动程序. * jdbcUsername: 用于连接数据库的用户名. * jdbcPassword: 用于连接数据库的密码.
基于提供的JDBC属性构造的数据源将具有默认链接: http://www.mybatis.org/ [MyBatis]连接池设置。 可以选择设置以下属性来调整该连接池(取自MyBatis文档):
-
jdbcMaxActiveConnections: 连接池中处于被使用状态的连接的最大值。默认为10。
-
jdbcMaxIdleConnections: 连接池中处于空闲状态的连接的最大值。
-
jdbcMaxCheckoutTime: 连接被取出使用的最长时间,超过时间会被强制回收。 默认为20000(20秒)。
-
jdbcMaxWaitTime:这是一个底层配置,让连接池可以在长时间无法获得连接时, 打印一条日志,并重新尝试获取一个连接。(避免因为错误配置导致沉默的操作失败)。 默认为20000(20秒)。
示例数据库配置:
1
2
3
4
<property name="jdbcUrl" value="jdbc:h2:mem:flowable_dmn;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
我们的基准测试表明,在处理大量并发请求时,MyBatis连接池可能扛不住。 因此,我们建议使用javax.sql.DataSource实现并将其注入流程引擎配置(例如HikariCP,Tomcat JDBC连接池等):
1
2
3
4
5
6
7
8
9
10
11
12
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/flowable_dmn" />
<property name="username" value="flowable" />
<property name="password" value="flowable" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
<property name="dataSource" ref="dataSource" />
...
请注意,Flowable 表单不附带允许您定义此类数据源的库。 所以你必须确保库在你的类路径上。
无论您使用的是JDBC还是数据源方法,都可以设置以下属性:
-
databaseType: 数据库类型,可以是如下的值(h2, mysql, oracle, postgres, mssql, db2).
-
databaseSchemaUpdate:允许您设置策略以在表单引擎启动和关闭时如何处理数据库表.
-
false(default): 在创建表单引擎时检查库模式的版本,如果版本不匹配则抛出异常. -
true: 在构建表单引擎时,执行检查并在必要时执行模式的更新。 如果schema不存在,则创建它. -
create-drop: 在创建表单引擎时创建schema,并在关闭流程引擎时删除schema.
-
2.5. JNDI方式数据源配置
默认情况下,Flowable Form的数据库配置包含在每个Web应用程序的WEB-INF/classes中的db.properties文件中。 这并不总是理想的,因为它 要求用户修改Flowable源中的db.properties并重新编译WAR文件,或者在每次部署时分解WAR并修改db.properties。 通过使用JNDI(Java命名和目录接口)获取数据库连接,连接完全由Servlet容器管理,并且可以在WAR部署之外管理配置。 这也允许对db.properties文件提供的连接参数进行更多控制。
2.5.1. 配置
JNDI数据源的配置将根据您使用的servlet容器应用程序而有所不同。 以下说明适用于Tomcat,但对于其他容器应用程序,请参阅容器应用程序的文档。
如果使用Tomcat,则在$CATALINA_BASE/conf/[enginename]/[hostname]/[warname].xml中配置JNDI资源(对于Flowable UI,这通常是$CATALINA_BASE/conf/Catalina/localhost/flowable-app。XML)。 首次部署应用程序时,将从Flowable WAR文件复制默认上下文,因此如果已存在,则需要替换它。 例如,要更改JNDI资源以便应用程序连接到MySQL而不是H2,请将文件更改为以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/flowable-app">
<Resource auth="Container"
name="jdbc/flowableDB"
type="javax.sql.DataSource"
description="JDBC DataSource"
url="jdbc:mysql://localhost:3306/flowable"
driverClassName="com.mysql.jdbc.Driver"
username="sa"
password=""
defaultAutoCommit="false"
initialSize="5"
maxWait="5000"
maxActive="120"
maxIdle="5"/>
</Context>
2.5.2. JNDI 属性
要配置JNDI数据源,请在Flowable UI的属性文件中使用以下属性:
-
spring.datasource.jndi-name=: 数据源的JNDI名称.
-
datasource.jndi.resourceRef: 设置查询是否发生在J2EE容器中,换句话说,如果JNDI名称尚未包含它,则需要添加前缀“java:comp/env/”。 默认为“true”.
2.6. 支持的数据库厂商
下面列出了Flowable用于引用数据库的类型(区分大小写!)。
| 数据库类型 | 连接URL | Notes |
|---|---|---|
h2 |
jdbc:h2:tcp://localhost/flowable_form |
Default configured database |
mysql |
jdbc:mysql://localhost:3306/flowable_form?autoReconnect=true |
Tested using mysql-connector-java database driver |
oracle |
jdbc:oracle:thin:@localhost:1521:xe |
|
postgres |
jdbc:postgresql://localhost:5432/flowable_form |
|
db2 |
jdbc:db2://localhost:50000/flowable_form |
|
mssql |
jdbc:sqlserver://localhost:1433;databaseName=flowable_form (jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver) OR jdbc:jtds:sqlserver://localhost:1433/flowable_form (jdbc.driver=net.sourceforge.jtds.jdbc.Driver) |
Tested using Microsoft JDBC Driver 4.0 (sqljdbc4.jar) and JTDS Driver |
2.7. 创建表
Flowable表单使用链接:http://www.liquibase.org[Liquibase]来跟踪,管理和应用数据库架构更改。 为数据库创建数据库表的最简单方法是:
-
在classpath中添加flowable-form-engine JARS包
-
添加合适的数据库驱动
-
将Flowable配置文件(flowable.form.cfg.xml)添加到类路径中,指向您的数据库(请参阅<< databaseConfiguration,数据库配置部分>>)
-
执行DbSchemaCreate类的main方法
2.8. 数据库表名称解释
Flowable表单的数据库名称都以ACT_FO_开头。
-
ACT_FO_DATABASECHANGELOG: Liquibase使用此表来跟踪已运行的changesets.
-
ACT_FO_DATABASECHANGELOGLOCK: Liquibase使用此表来确保一次只运行一个Liquibase实例.
-
ACT_FO_FORM_DEFINITION: 此表包含已部署的表单定义的定义信息.
-
ACT_FO_FORM_INSTANCE: 此表包含具有已由用户填写的值的表单实例.
-
ACT_FO_FORM_DEPLOYMENT: 该表包含部署元数据.
-
ACT_FO_FORM_RESOURCE: 此表包含表单定义资源.
2.9. 数据库升级
在运行升级之前,请确保备份数据库(使用数据库备份功能)。
默认情况下,每次创建流程引擎时都会执行版本检查。 这通常在应用程序或Flowable Web应用程序的引导时发生一次。 如果Flowable库注意到库版本与Flowable数据库表的版本之间的差异,则抛出异常。
要升级,必须首先将以下配置属性放在flowable.form.cfg.xml配置文件中:
1
2
3
4
5
6
7
8
9
<beans >
<bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
<!-- ... -->
<property name="databaseSchemaUpdate" value="true" />
<!-- ... -->
</bean>
</beans>
使用databaseSchemaUpdate设置为true即可。
2.10. 部署缓存配置
所有定义都被缓存(在解析之后),以避免每次需要表单时都访问数据库,并且表单数据不会更改。 默认情况下,此缓存没有限制。 要限制表单缓存使用的容器大小,请添加以下属性:
1<property name="formCacheLimit" value="10" />
设置此属性将使默认的LRU算法。 当然,此属性的“最佳”值取决于存储的表单总量和运行时实际使用的表单数。
您也可以注入自己的缓存实现。 自定义类必须实现org.flowable.form.engine.impl.persistence.deploy.DeploymentCache接口的bean:
1
2
3
<property name="formCache">
<bean class="org.flowable.MyCache" />
</property>
2.11. 日志
所有日志记录(flowable,spring,mybatis,…)都通过SLF4J进行路由,并允许选择您选择的日志记录实现。
*默认情况下,flowable-dmn-engine依赖项中不存在SFL4J-binding jar,这应该在项目中添加,以便使用您选择的日志框架。 *如果没有添加实现jar,SLF4J将使用NOP-logger,不记录任何内容,除了警告不会记录任何内容。 有关这些绑定链接的更多信息,请访问:http://www.slf4j.org/codes.html#StaticLoggerBinder[http://www.slf4j.org/codes.html#StaticLoggerBinder]。 使用Maven,添加例如这样的依赖(这里使用log4j),请注意您仍然需要添加一个版本:
1
2
3
4
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
flowable-ui和flowable-rest webapps配置了使用Log4j binding.。 在运行所有flowable-*模块的测试时也使用Log4j。
在类路径中使用带有commons-logging的容器时的重要注意事项: 为了通过SLF4J路由spring-logging,使用了一个桥接器(参见链接:http://www.slf4j.org/legacy.html#jclOverSLF4J[http://www.slf4j.org/legacy.html#jclOverSLF4J])。 如果您的容器提供了commons-logging实现,请按照此页面上的说明进行操作:http://www.slf4j.org/codes.html#release[http://www.slf4j.org/codes.html#release]确保稳定性。
使用Maven时的示例(省略版本):
1
2
3
4
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
3. Flowable 表单 API
3.1. 表单引擎 API 与服务类
表单引擎 API 是与 Flowable 表单交互的最常用方式。核心起点是可以通过 配置部分 中描述的几种方式创建的表单引擎。从表单引擎中,您能够获得各种其他服务类。
表单引擎和其服务类对象是线程安全的,因此您可以为整个服务保留其中一个引用。
1
2
3
4
5
FormEngine formEngine = FormEngines.getDefaultFormEngine();
FormRuleService formRuleService = formEngine.getFormRuleService();
FormRepositoryService formRepositoryService = formEngine.getFormRepositoryService();
FormService formService = formEngine.getFormService();
FormManagementService formManagementService = formEngine.getFormManagementService();
FormEngines.getDefaultFormEngine() 将在第一次调用时初始化并构建一个表单引擎,之后调用总是返回相同的表单引擎。使用 FormEngines.init() 和 FormEngines.destroy() 可以正确创建和关闭所有表单引擎。
FormEngines类将扫描所有 flowable.form.cfg.xml 和 flowable-form-context.xml 配置文件。对于所有 flowable.form.cfg.xml 配置文件,表单引擎将以典型的Flowable方式构建:FormEngineConfiguration.createFormEngineConfigurationFromInputStream(inputStream).buildFormEngine()。对于所有 flowable-form-context.xml 配置文件,表单引擎将以Spring方式构建:首先创建Spring应用程序上下文,然后表单引擎会从该应用程序上下文中获取。
所有的服务类均是无状态的。这意味着您可以轻松地在群集中的多个节点上运行Flowable表单模块,每个节点都连接同一个数据库,而不必担心哪台机器实际执行了旧的调用。对任何服务类的任何调用都是幂等的,无论它在何处执行。
FormRepositoryService 可能是Flowable表单引擎工作时所需的第一个服务类。该服务类提供用于管理和使用部署文件和表单定义的操作。表单定义是表单模型的根本概念(表单定义的主要概念在 表单介绍部分中进行了解释)。
部署文件是 Flowable 表单引擎中的打包最小单元。一个部署文件中可以包含多个表单定义的JSON 文件。发布一个部署文件意味着将其部署到引擎相关表中,在该引擎中,所有表单定义在存储到数据库之前都会被校验和解析。从那一刻起,系统会感知到这个部署文件,并且部署文件中包含的任何表单都可以被执行。
此外,这个服务类允许您:
-
查询引擎已知的表单定义的部署文件。
-
检索表单定义的POJO类,它可用于使用Java中而不是JSON数据结构。
FormService 提供了使用用户为特定表单定义填写的值来创建表单实例的方法。它也可以被用于查询表单实例。
使用 Flowable 表单模块编写自定义应用程序时,通常不需要 FormManagementService 。它允许您检索有关引擎版本,数据库表和表元数据的信息。
3.2. 异常策略
Flowable中的基础异常是 org.flowable.engine.FlowableException,这是一个未经检查的异常。这种异常可以被API随时抛出,其他特定方法中发生的“预期中的”异常被记录在文档中。例如 FormRuleService 的摘录:
尽管我们想要避免一个大的异常层次结构,下列的异常子类仍会在特定情况下被抛出。在流程执行或 API 调用期间发生的所有其他错误都不适合下面可能发生的异常,这些错误将作为常规 FlowableExceptions 抛出。
-
FlowableOptimisticLockingException:当由同一数据条目的并发访问引起的数据存储中发生乐观锁问题时抛出。 -
FlowableClassLoadingException:当未找到请求加载的类或加载时发生错误时抛出。 -
FlowableObjectNotFoundException:当请求或操作的对象不存在时抛出。 -
FlowableIllegalArgumentException:这个异常表示在Flowable 表单 API调用中使用了非法参数、在引擎的配置中配置了非法值或者提供了非法值。
3.3. 查询 API
有两种方法可以从引擎查询数据:使用查询 API 和本地查询。查询 API 允许您使用流畅的 API 编写完全类型安全的查询。您可以为查询添加各种查询条件(所有条件共同应用逻辑与)与一个排序参数。示例如下:
1
2
3
4
List<FormDeployment> formDeployments = formRepositoryService.createDeploymentQuery()
.deploymentNameLike("deployment%")
.orderByDeployTime()
.list();
有时您需要更强大的查询操作,例如,使用或运算符或使用查询 API 无法表达的查询。对于这些情况,我们引入了本地查询,允许您编写自己的 SQL 语句进行查询。返回类型由您使用的查询对象定义,数据会映射到正确的对象,例如 Deployment、FormInstance 等。由于查询将在数据库中触发,因此必须使用在数据库中定义的表名和列名,这需要一些有关内部数据结构的知识,建议谨慎使用本机查询。表名可以通过 API 进行检索,以使依赖尽可能小。
1
2
3
4
5
6
7
8
long count = formRepositoryService.createNativeDeploymentQuery()
.sql("SELECT count(*) FROM " + formManagementService.getTableName(FormDeploymentEntity.class) + " D1, "
+ formManagementService.getTableName(FormDefinitionEntity.class) + " D2 "
+ "WHERE D1.ID_ = D2.DEPLOYMENT_ID_ "
+ "AND D1.ID_ = #{deploymentId}")
.parameter("deploymentId", deployment.getId())
.count();
3.4. 单元测试
由于 Flowable 表单模块是一个嵌入式的 Java 引擎,因此为表单定义编写单元测试就像编写常规单元测试一样简单。
Flowable 支持 JUnit 4、JUnit 5 做单元测试。
在编写JUnit 5单元测试时,可以使用 org.flowable.form.engine.test.FlowableFormExtension。
通过此扩展,表单引擎和服务类可用作测试和生命周期方法的参数。
使用此拓展将启用 org.flowable.form.engine.test.FormDeploymentAnnotation 注解(请参阅下面有关其使用和配置的说明),它将在类路径中查找默认配置文件。
使用相同的配置文件时,表单引擎会在多个单元测试中静态缓存。
当使用 @FormDeploymentAnnotation 注解测试方法时,在每次测试之前,将发布在+ FormDeploymentAnnotation#resources +中定义的表单文件。
如果没有定义资源,将发布与测试类在同一包中的 testClassName.testMethod.form 形式的资源文件。
在测试结束时,部署文件将会删除,包括所有相关的表单实例、定义等。
有关更多信息,请参阅 FormDeploymentAnnotation 类。
在编写JUnit 4单元测试时,可以使用 org.flowable.form.engine.test.FlowableFormRule 规则。通过这个规则,表单引擎和服务类可以通过 getter 方法获得。包括这个规则将允许使用 org.flowable.form.engine.test.FormDeploymentAnnotation 注解(参见上面有关其使用和配置的说明),它将在类路径上查找默认配置文件。使用相同的配置文件时,表单引擎会在多个单元测试中静态缓存。
也可以为规则提供自定义的引擎配置。
以下代码片段显示了使用 JUnit 5单元测试的示例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ExtendWith(FlowableFormExtension.class)
// 如果需要自定义表单配置,则应取消注释下面的部分
//@FormConfigurationResource("custom1.flowable.form.cfg.xml")
class MyFormDefinitionTest {
private FormEngine formEngine;
@BeforeEach
void setUp(FormEngine formEngine) {
this.formEngine = formEngine;
}
@Test
@FormDeploymentAnnotation
void formUsageExample() {
FormService formService = formEngine.getFormService();
FormInstance result = formService.getFormInstanceModelById(
"f7689f79-f1cc-11e6-8549-acde48001122", null);
Assertions.assertNotNull(result);
}
}
以下代码片段显示了使用 JUnit 4单元测试和 FlowableFormRule (传递可选的自定义配置)的示例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyFormDefinitionTest {
@Rule
public FlowableFormRule flowableFormRule = new FlowableFormRule("custom1.flowable.form.cfg.xml");
@Test
@FormDeploymentAnnotation
public void formUsageExample() {
FormEngine formEngine = flowableFormRule.getFormEngine();
FormService formService = dmnEngine.getFormService();
FormInstance result = formService.getFormInstanceModelById(
"f7689f79-f1cc-11e6-8549-acde48001122", null);
Assert.assertNotNull(result));
}
}
3.5. Web 应用程序中的表单引擎
FormEngine 是一个线程安全的类,可以很容易地在多个线程之间共享。在 Web 应用程序中,这意味着可以在容器启动时创建一次表单引擎,并在容器关闭时关闭引擎。
以下代码片段显示了如何在普通的 Servlet 环境中编写一个简单的 ServletContextListener 来初始化和销毁表单引擎:
1
2
3
4
5
6
7
8
9
10
11
public class FormEnginesServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
FormEngines.init();
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
FormEngines.destroy();
}
}
contextInitialized 方法将委托给 FormEngines.init()。将在类路径中查找 flowable.form.cfg.xml 配置文件,并为给定的配置创建 FormEngine (例如,带有配置文件的多个JAR)。如果类路径上有多个这样的配置文件,请确保它们都有不同的名称。当需要 Form 引擎时,可以使用以下命令获取它:
1FormEngines.getDefaultFormEngine()
或者
1FormEngines.getFormEngine("myName");
当然,也可以如 配置部分 所述,使用创建表单引擎的任何变体。
上下文监听器的 contextDestroyed 方法委托给FormEngines.destroy()。这将正确关闭所有初始化的表单引擎。
4. 集成Spring
虽然你可以在没有Spring的情况下使用Flowable 表单,但我们提供了一些非常好的集成功能,本章将对此进行说明。
4.1. FormEngineFactoryBean
表单引擎可以按照常规的Spring bean方式进行配置.整合引用到的类是org.flowable.form.spring.FormEngineFactoryBean.该bean持有一个表单引擎配置类并创建表单引擎.这意味着Spring属性的创建和配置与 configuration section 中记录的相同.关于Spring集成和配置引擎bean如下所示
1
2
3
4
5
6
7
<bean id="formEngineConfiguration" class="org.flowable.form.spring.SpringFormEngineConfiguration">
...
</bean>
<bean id="formEngine" class="org.flowable.form.spring.FormEngineFactoryBean">
<property name="formEngineConfiguration" ref="formEngineConfiguration" />
</bean>
注意,formEngineConfiguration bean现在使用的是 org.flowable.form.spring.SpringFormEngineConfiguration 类。
4.2. 自动部署资源
集成Spring还具有部署资源的特性。在配置表单引擎时,您可以指定一组资源.当表单引擎被创建时,将扫描和部署这些资源并过滤防止重复部署。只有资源被更改时,才会将重新部署部署到Flowable 表单数据库.这在经常重启包含大量表单资源的Spring容器中具有很大的意义(例如,测试)
例如:
1
2
3
4
5
6
7
8
9
<bean id="formEngineConfiguration" class="org.flowable.spring.SpringFormEngineConfiguration">
...
<property name="deploymentResources"
value="classpath*:/org/flowable/spring/test/autodeployment/autodeploy/*.form" />
</bean>
<bean id="formEngine" class="org.flowable.form.spring.FormEngineFactoryBean">
<property name="formEngineConfiguration" ref="formEngineConfiguration" />
</bean>
默认情况下,上面的配置会将匹配过滤后的所有资源进行分组并单独部署到Flowable 表单引擎中,在整个部署过程中重复过滤以防止重新部署未更改的资源.在某些情况下,你可能并不想这么做.例如,如果以这种方式部署一组表单资源,并且这些资源中只有一个表单定义更改了,整个流程定义部署将被视为新的并且被重新部署,尽管实际上只改变了一个但是每个表单都被定义为了新的版本,
为了能够自定义部署的方式,您可以在 SpringFormEngineConfiguration 中,指定 deploymentMode 属性。该属性定义了从过滤器匹配的资源集合以及确定部署的方式。默认情况下,该属性提供3个默认属性:
-
default: 将所有资源分组到单个部署中,并对该部署应用重复过滤。如果您未指定其他值,将默认使用它。 -
single-resource: 为每个单独的资源单独部署,并对该部署应用重复过滤。适用于单独部署某个已更改表单定义的资源,仅创建该表单定义的新版本。 -
resource-parent-folder: 为共享同一父文件夹的资源创建单独的部署,并对该部署应用重复过滤。适用于为大多数资源创建单独的部署,但仍可以通过将它们放在共享文件夹中来对其进行分组。以下是为deploymentMode属性指定single-resource配置的示例:
1
2
3
4
5
6
<bean id="formEngineConfiguration"
class="org.flowable.form.spring.SpringFormEngineConfiguration">
...
<property name="deploymentResources" value="classpath*:/flowable/*.form" />
<property name="deploymentMode" value="single-resource" />
</bean>
除了使用上面列出的 deploymentMode 属性之外,您还可以自定义属性来实现部署。如果需要,您可以创建 SpringFormEngineConfiguration 的子类并重写+getAutoDeploymentStrategy(String deploymentMode)+ 方法。该法确定将哪个部署策略用于 deploymentMode 配置的特定值。
4.3. 单元测试
与Spring集成时,使用标准的Flowable testing facilities来测试表单将会变得非常简单. 以下示例展示了如何在基于Spring的JUnit 4和5测试中测试表单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@ExtendWith(FlowableFormSpringExtension.class)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = SpringJunitJupiterTest.TestConfiguration.class)
public class SpringJunit4Test {
@Autowired
private FormEngine formEngine;
@Autowired
private FormService formService;
@Test
@FormDeploymentAnnotation
public void simpleFormInstanceTest() {
FormInstance result = formService.getFormInstanceModelById(
"f7689f79-f1cc-11e6-8549-acde48001122", null);
Assertions.assertNotNull(result));
}
}
使用 FlowableFormSpringExtension 时允许使用 Deployment 注解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:org/flowable/spring/test/junit4/springTypicalUsageTest-context.xml")
public class SpringJunit4Test {
@Autowired
private FormEngine formEngine;
@Autowired
private FormService formService;
@Autowired
@Rule
public FlowableFormRule flowableSpringRule;
@Test
@FormDeploymentAnnotation
public void simpleFormInstanceTest() {
FormInstance result = formService.getFormInstanceModelById(
"f7689f79-f1cc-11e6-8549-acde48001122", null);
Assert.assertNotNull(result));
}
}
注意,在测试时,您需要在Spring配置中定义 org.flowable.form.engine.test.FlowableFormRule bean(在上面的示例中通过自动装配注入)。
1
2
3
<bean id="flowableFormRule" class="org.flowable.form.engine.test.FlowableFormRule">
<property name="formEngine" ref="formEngine"/>
</bean>
5. 部署
5.1. 表单定义
表单定义带有.form后缀名,可以被部署到表单引擎。
当表单引擎接入流程引擎后,表单定义和与此流程相关其他资源,将被打包进一个业务存档(BAR, Business archive)中。若使用了 flowable-form-engine-configurator 或 flowable-form-spring-configurator 模块,流程引擎部署服务将负责把表单资源部署到流程引擎中。
5.1.1. 表单定义
每个表单定义由一个或多个表单字段定义组成。当部署一个表单定义时,其信息将会被插入到 ACT_FO_FORM_DEFINITION 表中。
5.1.2. 编程方式部署
可使用如下方式部署一个表单定义:
1
2
3
4
5
6
7
String formDefinition = "path/to/definition-one.form";
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(barFileName));
formRepositoryService.createDeployment()
.name("definition-one")
.addClasspathResource(formDefinition)
.deploy();
5.2. 表单定义的版本管理
表单定义的版本会在部署期间创建,Flowable在将表单定义存储到表单数据库前,为其分配一个版本。
对于每个表单定义,执行以下步骤来初始化这些属性key、version、 name和id:
-
表单定义JSON文件中的
key属性,被用作数据库中表单定义信息表的key属性。 -
表单定义JSON文件中的
name属性,被用作数据库中表单定义信息表的name属性。 -
当首次以一个特定的
key属性部署表单定义时,将分配版本为1。对于具有相同key属性表单定义的所有后续部署,版本将设置为当前已部署的最大版本号加1。key属性用来区分不同的表单定义。 -
id属性是一个唯一的编号,用以保证在集群环境下,流程定义缓存中,流程id的唯一性。
表单定义示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"key": "form1",
"name": "My first form",
"fields": [
{
"id": "input1",
"name": "Input1",
"type": "text",
"required": false,
"placeholder": "empty"
}
]
}
当部署此表单定义后,数据库中表单定义信息表将如下所示:
| id | key | name | version |
|---|---|---|---|
e29d4126-ed4d-11e6-9e00-7282cbd6ce64 |
form1 |
My first form |
1 |
假设我们现在部署相同表单定义的一个更新版本(例如,更改文本变量),但表单定义的key属性保持不变。数据库中表单定义信息表将包含以下条目:
| id | key | name | version |
|---|---|---|---|
e29d4126-ed4d-11e6-9e00-7282cbd6ce64 |
form1 |
My first form |
1 |
e9c2a6c0-c085-11e6-9096-6ab56fad108a |
form1 |
My first form |
2 |
如果我们创建第二个表单定义,如下所示,并将其部署到Flowable表单引擎,第三行将会添加到表中。
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"key": "form2",
"name": "My second form",
"fields": [
{
"id": "input2",
"name": "Input2",
"type": "text",
"required": false,
"placeholder": "empty"
}
]
}
数据库中表单定义信息表将如下所示:
| id | key | name | version |
|---|---|---|---|
e29d4126-ed4d-11e6-9e00-7282cbd6ce64 |
form1 |
My first form |
1 |
e9c2a6c0-c085-11e6-9096-6ab56fad108a |
form1 |
My first form |
2 |
d317d3f7-e948-11e6-9ce6-b28c070b517d |
form2 |
My second form |
1 |
请注意新表单定义的key属性与第一个表单定义不同。 Flowable表单引擎仅使用key属性区分表单定义。因此,新的表单定义部署版本为1。
5.3. 类别
表单部署和表单定义都可以具有用户定义的类别。 部署类别可以在如下API中指定:
1
2
3
4
5
formRepository
.createDeployment()
.category("yourCategory")
...
.deploy();
表单定义类别可以在如下API中指定:
1formRepository.setFormDefinitionCategory("e9c2a6c0-c085-11e6-9096-6ab56fad108a", "yourCategory");
6. 表单介绍
6.1. 表单定义是什么?
对于BPMN引擎而言,我们沿用了BPMN规范,同理对与DMN引擎,我们使用了DMN规范。但是对于开始或任务表单,并不存在类似的共性问题让我们使用。因此,我们自己定义了一个基于JSON格式的的表单结构定义,我们使用这种结构作为Flowable表单编辑器的输出格式,而且我们会在Flowable任务应用中提取该结构让开始或任务表单使用。
6.2. Defining a form
用你最爱的文本或JSON编辑器新建一个JSON文件,然后给这个文件起个个性的名字。确保这个文件的后缀为.form,比如shareniu.fom,否则表单引擎将无法部署此文件。
表单的JSON定义以key、name和description开头。表单引擎通过属性key来辨别表单在整个表单引擎中的唯一身份。对于来源相同的同一个表单定义的版本系统也是基于属性key运作的。第二部分是一个数组类型fields,表单定义的字段在这里阐明。第三部分是可选的,用来定义表单的结果outcomes。示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"key": "form1",
"name": "My first form",
"fields": [
{
"id": "input1",
"name": "Input1",
"type": "text",
"required": false,
"placeholder": "empty"
}
],
"outcomes": [
{
"id": "null",
"name": "Accept"
},
{
"id": "null",
"name": "Reject"
}
]
}
每个表单字段都有一个id、name和type属性。在同一个表单定义中id应该是独一无二的。当一个用户完成表单后id还能当作变量名使用。在这个小例子中,一个名叫input1的流程变量被创建了,用户填入这个文本字段里的东西就是这个变量的值。结果outcomes也可以被映射成一个变量,此变量基于表单标识符,格式为:"form_<form-identifier>_outcome"。举例说明,选中的结果会被设置为一个名叫"form_form1_outcome"的变量。你可以通过表达式${form_form1_outcome == "Accept"}来检验结果outcome是否为’Accept'
表单支持以下类型字段
-
text: 文本字段
-
multi-line-text: 多行文本字段
-
integer: 文本字段,但是只允许数字类型的值
-
boolean: 复选框字段
-
date: 日期字段
-
dropdown: 选择框字段,定义字段时可以设置选项的值
-
radio-buttons: 单选字段,定义字段时可以设置选项的值
-
people: 选择框字段,可以选中用户表里的一个用户
-
functional-group: 选择框字段,可以选中分组表里的一个组
-
upload: 上传文件字段
-
expression: 一个标签,在标签文本中你可以运用JUEL表达式操作变量或其他动态的值
7. REST API
7.1. Flowable REST一般原则
7.1.1. 安装与认证
Flowable为Flowable引擎提供了REST API,可以通过在servlet容器(如Apache Tomcat)中部署flowable-rest.war文件来安装。另外,也可以通过在应用中引入servlet(包括对应的映射),并将所有flowable-rest的依赖加入classpath的方式使用。
默认情况下Flowable引擎会连接至一个H2内存数据库。可以通过WEB-INF/META-INF/flowable-app文件夹下的flowable-app.properties文件修改数据库设置。REST API使用JSON格式( http://www.json.org ),并基于Spring MVC( http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html )构建。
默认情况下访问任何REST资源都需要具有rest-access-api权限的合法用户。如果需要任何合法用户都可以访问REST API,可以将flowable.rest.app.authentication-mode设置为any-user(这也是之前版本Flowable的默认设置)。
通过如下参数设置可以访问REST API的默认用户:
flowable.rest.app.admin.user-id=rest-admin flowable.rest.app.admin.password=test flowable.rest.app.admin.first-name=Rest flowable.rest.app.admin.last-name=Admin
当REST应用启动时,如果用户不存在或无法找到,则会创建该用户。这个用户会被赋予访问REST API所需的access-rest-api权限。请不要忘记修改这个用户的密码。如果未设置flowable.rest.app.admin.user-id,则不会创建用户或权限。也因为此,在初始化完成后删除这些参数,并不会删除之前已经配置的用户或权限。
使用基础HTTP访问认证,因此在请求时,需要在HTTP-header中添加 Authorization: Basic …== 。也可以在请求url中包含用户名与密码(如 http://username:password@localhost:8080/xyz)。
建议使用基础认证时,同时使用HTTPS。
7.1.2. 配置
Flowable REST web应用使用Spring Java Configuration来启动Flowable引擎,使用Spring security定义基础认证安全,并为为特定的变量处理定义了变量转换。 有少量参数可以通过修改WEB-INF/classes文件夹下的engine.properties文件定义。 如果需要高级配置选项,可以在flowable-custom-context.xml文件中覆盖默认的Spring bean,这个文件也在WEB-INF/classes文件夹下。 该文件中已经以注释形式提供了示例配置。也可以在该文件中定义一个新的命名为restResponsefactory的Spring bean,覆盖默认的RestResponseFactory,并使用自定义实现类。
7.1.3. 在Tomcat中使用
由于Tomcat中的默认安全参数,默认不能使用转义斜线符(%2F与%5C)(将返回400)。这可能会影响部署资源与其数据URL,因为URL可能包含转义斜线符。
当发现400异常结果时,可以设置下列系统参数:
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
最佳实践是(在post/put JSON时),在下面介绍的HTTP请求中,永远将Accept与Content-TypeHTTP头设置为application/json。
7.1.4. 方法与返回码
| 方法 | 操作 |
|---|---|
|
获取单个资源,或获取一组资源。 |
|
创建一个新资源。在查询结构太复杂,不能放入GET请求的查询URL中时,也用于执行资源查询。 |
|
更新一个已有资源的参数。也用于调用已有资源提供的操作。 |
|
删除一个已有资源。 |
| 响应 | 描述 |
|---|---|
|
操作成功,返回响应( |
|
操作成功,已经创建了实体,并在响应体中返回( |
|
操作成功,已经删除了实体,因此没有返回的响应体( |
|
操作失败。操作要求设置认证头。如果请求中有认证头,则提供的鉴证并不合法,或者用户未被授权进行该操作。 |
|
操作被禁止,且不应重试。这不是鉴证或授权的问题,而是说明不允许该操作。例如:无论任何用户或流程/任务的状态,删除一个运行中流程的任务是且永远是不允许的。 |
|
操作失败。请求的资源未找到。 |
|
操作失败。使用的方法不能用于该资源。例如,更新(PUT)部署资源将返回 |
|
操作失败。该操作导致更新一个已被其他操作更新的资源,因此本更新不再有效。也可以表示正在为一个集合创建一个资源,但该标识符已存在。 |
|
操作失败。请求提包含了不支持的媒体类型。也会发生在请求体JSON中包含了未知的属性或值,但没有可用的格式/类型来处理的情况。 |
|
操作失败。执行操作时发生了未知异常。响应体中包含了错误的细节。 |
HTTP响应的media-type总是application/json,除非请求的是二进制内容(例如部署资源数据)。这时将使用内容的media-type。
7.1.5. 错误响应体
当发生错误时(可能是客户端或服务器端的错误,4XX及5XX状态码),响应体会包含一个描述了发生的错误的对象。任务未找到时的404状态的例子:
1
2
3
4
{
"statusCode" : 404,
"errorMessage" : "Could not find a task with id '444'."
}
7.1.6. 请求参数
URL片段
作为url的一部分的参数(例如,URL编码或百分号编码)。大多数框架都内建了这个功能,但要记得考虑它。特别是对可能包含斜线符的段落(例如部署资源),就必须要做转义。
Rest URL查询参数
作为查询字符串添加在URL中的参数(例如http://host/flowable-rest/service/deployments?name=Deployment中的name参数)可以使用下列类型。在相应的REST-API文档中也会提到:
| 类型 | 格式 |
|---|---|
String |
纯文本参数。可以包含任何URL允许的合法字符。对于 |
Integer |
整形参数。只能包含数字型非小数值,在-2.147.483.648至2.147.483.647之间。 |
Long |
长整形参数。只能包含数字型非小数值,在-9.223.372.036.854.775.808至9.223.372.036.854.775.807之间。 |
Boolean |
boolean型参数。可以为 |
Date |
日期型参数。使用ISO-8601日期格式(参考wikipedia中的ISO-8601),使用时间与日期部分(例如 |
JSON body 参数
| 类型 | 格式 |
|---|---|
String |
纯文本参数。对于 |
Integer |
整形参数,使用JSON数字。只能包含数字型非小数值,在-2.147.483.648至2.147.483.647之间。 |
Long |
长整形参数,使用JSON数字。只能包含数字型非小数值,在-9.223.372.036.854.775.808至9.223.372.036.854.775.807之间。 |
Date |
日期型参数,使用JSON文本。使用ISO-8601日期格式(参考wikipedia中的ISO-8601),使用时间与日期组分(例如 |
分页与排序
分页与排序参数可以作为查询字符串加入URL中(例如http://host/flowable-rest/service/deployments?sort=name中的name参数)。
| 参数 | 默认值 | 描述 |
|---|---|---|
sort |
各查询实现不同 |
排序键的名字,在各查询实现中默认值与可用值都不同。 |
order |
asc |
排序顺序,可以是’asc'(顺序)或’desc'(逆序)。 |
start |
0 |
对结果分页的参数。默认结果从0开始。 |
size |
10 |
对结果分页的参数。默认大小为10. |
JSON查询变量格式
1
2
3
4
5
6
7
{
"name" : "variableName",
"value" : "variableValue",
"operation" : "equals",
"type" : "string"
}
| 参数 | 必填 | 描述 |
|---|---|---|
name |
否 |
包含在查询中的变量名。在有些使用' |
value |
是 |
包含在查询中的变量值,需要使用给定类型的正确格式。 |
operator |
是 |
查询使用的操作,可以为下列值: |
type |
否 |
所用变量的类型。当省略时,会从 |
| 类型名 | 描述 |
|---|---|
string |
值处理转换为 |
short |
值处理转换为 |
integer |
值处理转换为 |
long |
值处理转换为 |
double |
值处理转换为 |
boolean |
值处理转换为 |
date |
值处理转换为 |
变量表示
读取与写入变量(执行选择)时,REST API都使用通用原则与JSON格式。变量的JSON表示为:
1
2
3
4
5
6
{
"name" : "variableName",
"value" : "variableValue",
"valueUrl" : "http://...",
"type" : "string"
}
| 参数 | 必填 | 描述 |
|---|---|---|
name |
是 |
变量名。 |
value |
否 |
变量的值。当写入变量且省略了 |
valueUrl |
否 |
当读取 |
type |
否 |
变量的类型。查看下面的表格了解类型的更多信息。当写入变量且省略了这个值时,将使用请求的原始JSON属性类型推断,限制在 |
| 类型名 | 描述 |
|---|---|
string |
值按照 |
integer |
值按照 |
short |
值按照 |
long |
值按照 |
double |
值按照 |
boolean |
值按照 |
date |
值按照 |
可以使用自定义JSON表示,以支持额外的变量类型(既可以是简单值,也可以是复杂/嵌套的JSON对象)。通过扩展org.flowable.rest.service.api.RestResponseFactory的initializeVariableConverters()方法,可以添加额外的org.flowable.rest.service.api.engine.variable.RestVariableConverter类,用于将POJO转换为适合通过REST传输的格式,以及将REST值转换为POJO。实际转换JSON使用Jackson。
7.2. 部署
当使用tomcat时, 请参考在Tomcat中的用法。
7.2.1. 部署列表
GET form-repository/deployments
| 参数名称 | 是否必须 | 参数类型 | 描述 |
|---|---|---|---|
name |
否 |
字符串 |
仅返回根据名称查询返回的部署结果集. |
name模糊查询 |
否 |
字符串 |
仅返回根据名称模糊匹配的部署结果集. |
category |
否 |
字符串 |
仅返回符合类别的部署结果集. |
不等于category |
否 |
字符串 |
仅返回不等于该类别的其他部署结果集. |
tenantId |
否 |
字符串 |
仅返回给符合租户ID的部署结果集. |
模糊匹配tenantId值 |
否 |
字符串 |
仅返回模糊匹配到租户ID值的部署结果集. |
withoutTenantId |
否 |
布尔 |
如果为 true 则仅返回未设置tenantId的部署。如果为 false 则忽略参数租户ID。 |
sort |
否 |
id (默认), 名称, 部署时间 or 租户ID |
要排序的属性要与 order 一起使用. |
普通的分页和排序可以用这个URL.
| 响应编码 | 描述 |
|---|---|
200 |
表示请求成功. |
成功响应正文:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"data": [
{
"id": "10",
"name": "flowable-form-examples",
"deploymentTime": "2010-10-13T14:54:26.750+02:00",
"category": "examples",
"url": "http://localhost:8081/form-api/form-repository/deployments/10",
"tenantId": null
}
],
"total": 1,
"start": 0,
"sort": "id",
"order": "asc",
"size": 1
}
7.2.2. 获取单个部署
GET form-repository/deployments/{deploymentId}
| 参数名称 | 是否必须 | 值类型 | 描述 |
|---|---|---|---|
部署ID |
是 |
字符串 |
根据部署ID获取部署信息. |
| 响应编码 | 描述 |
|---|---|
200 |
表示该部署信息已经找到并且返回. |
404 |
表示请求的部署信息未找到. |
成功响应体:
1
2
3
4
5
6
7
8
{
"id": "10",
"name": "flowable-form-examples",
"deploymentTime": "2010-10-13T14:54:26.750+02:00",
"category": "examples",
"url": "http://localhost:8081/form-api/form-repository/deployments/10",
"tenantId" : null
}
7.2.3. 创建部署信息
POST form-repository/deployments
请求正文:
请求正文应包含multipart / form-data类型的数据。 请求中应该只有一个文件,任何其他文件都将被忽略。 部署名称是传入的文件字段的名称。
可以在名称为tenantId的请求正文中传递附加参数(表单字段)。 此字段的值将用作完成此部署的租户的标识符。
| 响应编码 | 描述 |
|---|---|
201 |
表示已经部署成功. |
400 |
表示请求正文中不存在任何内容,或者部署不支持内容mime-type。 状态描述包含其他信息。 |
成功响应正文:
1
2
3
4
5
6
7
8
{
"id": "10",
"name": "simple.form",
"deploymentTime": "2010-10-13T14:54:26.750+02:00",
"category": null,
"url": "http://localhost:8081/form-api/form-repository/deployments/10",
"tenantId" : "myTenant"
}
7.2.4. 删除部署信息
DELETE form-repository/deployments/{deploymentId}
| 参数 | 是否必须 | 值类型 | 描述 |
|---|---|---|---|
部署ID |
是 |
字符串 |
要删除的部署的标识符。 |
| 响应编码 | 描述 |
|---|---|
204 |
表示已找到部署并已删除。 响应体是空的。 |
404 |
表示未找到请求的部署。 |
7.2.5. 获取部署资源内容
GET form-repository/deployments/{deploymentId}/resourcedata/{resourceId}
| 参数 | 是否必须 | 值类型 | 描述 |
|---|---|---|---|
部署ID |
是 |
字符串 |
请求的资源所属的部署标识符。 |
资源ID |
必须 |
字符串 |
获取数据的资源的标识符。 确保对resourceId进行URL编码,以防它包含正斜杠。 举个例子, 比如 forms%2Fmy-form.form 代替 forms/my-form.form. |
| 响应编码 | 描述 |
|---|---|
200 |
表示已找到部署和资源,并且已返回资源数据。 |
404 |
表示未找到请求的部署,或者部署中不存在具有给定ID的资源。 状态描述包含其他信息。 |
成功响应正文:
响应正文将包含所请求资源的二进制资源内容。 响应内容类型将与资源’mimeType’属性中返回的类型相同。 此外,还设置了内容处置标题,允许浏览器下载文件而不是显示文件。
7.3. 表单定义
7.3.1. 表单定义列表
GET form-repository/form-definitions
| 参数 | 是否必须 | 参数类型 | 描述 |
|---|---|---|---|
version |
否 |
整型 |
仅返回给定版本定义的表单. |
name |
否 |
字符串 |
仅返回给定名称的定义的表单。 |
根据name模糊匹配 |
否 |
字符串 |
仅返会根据名称模糊匹配到的定义表单 |
key |
否 |
字符串 |
仅返回具有给定键的表单定义。 |
模糊匹配key |
否 |
字符串 |
仅返回模糊匹配给定键的表单定义. |
resourceName |
否 |
字符串 |
仅返回具有给定资源名称的表单定义 |
模糊匹配resourceName |
否 |
字符串 |
仅返回具有模糊匹配资源名称的表单定义 |
category |
否 |
字符串 |
仅返回给定类别的表单定义。 |
模糊匹配category |
否 |
字符串 |
仅返回模糊匹配给定类别的表单定义。 |
不等于category |
否 |
字符串 |
仅返回非给定类别的表单定义。 |
deploymentId |
否 |
字符串 |
仅返回作为具有给定标识符的部署的一部分的表单定义。 |
latest |
否 |
布尔 |
仅返回最新的表单定义版本。 只能与’key’和’keyLike’参数一起使用,使用任何其他参数将导致400响应。 |
sort |
否 |
name (default), id, key, category, deploymentId 和 version |
要排序的属性,与“order”一起使用。 |
一般 分页和排序请求参数可以用在这个请求.
| 响应编码 | 描述 |
|---|---|
200 |
表示请求成功,并返回表单定义 |
400 |
表示参数以错误的格式传递,或者“latest”与“key”和“keyLike”以外的其他参数一起使用。 状态消息包含其他信息。 |
成功响应正文:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"data": [
{
"id" : "818e4703-f1d2-11e6-8549-acde48001122",
"url" : "http://localhost:8182/form-repository/form-definitions/simpleForm",
"version" : 1,
"key" : "simpleForm",
"category" : "Examples",
"deploymentId" : "818e4703-f1d2-11e6-8549-acde48001121",
"parentDeploymentId" : "2",
"name" : "The Simple Form",
"description" : "This is a form for testing purposes",
}
],
"total": 1,
"start": 0,
"sort": "name",
"order": "asc",
"size": 1
}
7.3.2. 获取定义的表单
GET repository/form-definitions/{formDefinitionId}
| 参数 | 是否必须 | 值类型 | 描述 |
|---|---|---|---|
formDefinitionId |
是 |
字符串 |
要获取的流程定义的标识符。 |
| Response code | Description |
|---|---|
响应编码 |
描述 |
200 |
表示已找到并返回表单定义。 |
404 |
表示找不到请求的表单定义。 |
成功返回例子:
1
2
3
4
5
6
7
8
9
10
11
{
"id" : "818e4703-f1d2-11e6-8549-acde48001122",
"url" : "http://localhost:8182/form-repository/form-definitions/simpleForm",
"version" : 1,
"key" : "simpleForm",
"category" : "Examples",
"deploymentId" : "818e4703-f1d2-11e6-8549-acde48001121",
"parentDeploymentId" : "2",
"name" : "The Simple Form",
"description" : "This is a form for testing purposes",
}
7.3.3. 获取表单定义资源内容
GET repository/form-definitions/{formDefinitionId}/resourcedata
| 参数名 | 是否必须 | 参数类型 | 描述 |
|---|---|---|---|
formDefinitionId |
是 |
字符串 |
用于获取资源数据的表单定义的标识符。 |
返回值:
返回的编码和响应体与+GET form-repository/deployment/{deploymentId}/resourcedata/{resourceId}+ 一样.
7.3.4. 获取定义表单的表单模型
GET form-repository/form-definitions/{formDefinitionId}/model
| 请求参数 | 是否必须 | 参数类型 | 描述 |
|---|---|---|---|
formDefinitionId |
是 |
字符串 |
获取模型的表单定义的标识符。 |
| 响应编码 | 描述 |
|---|---|
200 |
表示找到了表单定义并返回了模型. |
404 |
表示找不到请求的表单定义。 |
响应正文: 响应主体是+ org.flowable.form.model.FormModel +的JSON表示,并包含完整的表单定义模型。
7.4. 表单实例
7.4.1. 获取表单实例
GET form/form-instances/{formInstanceId}
| 请求参数 | 是否必须 | 参数类型 | 描述 |
|---|---|---|---|
formInstanceId |
是 |
字符串 |
要获取的表单实例的标识符。 |
| 响应编码 | 描述 |
|---|---|
200 |
表示找到并返回了表单实例. |
404 |
表示找不到请求的表单实例。 |
成功响应正文:
1
2
3
4
5
6
7
8
9
10
11
12
{
"id":"48b9ac82-f1d3-11e6-8549-acde48001122",
"url":"http://localhost:8182/form/form-instances/48b9ac82-f1d3-11e6-8549-acde48001122",
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"submittedDate":"2013-04-17T10:17:43.902+0000",
"submittedBy":"testUser",
"formValuesId":"818e4703-f1d2-11e6-8549-acde48001110",
"tenantId": null
}
7.4.2. 存储表单实例
POST form/form-instances
请求正文(以流程定义ID开头):
1
2
3
4
5
6
7
8
9
{
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"variables": {
"input1": "test"
}
}
请求正文(从表单定义键开始):
1
2
3
4
5
6
7
8
9
{
"formDefinitionKey":"simpleForm",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"variables": {
"input1": "test"
}
}
在请求正文中只能使用+ formDefinitionId 或 formDefinitionKey 中的一个。 参数+变量+和 tenantId 是可选的。 如果省略 tenantId +,将使用默认租户。 有关变量格式的更多信息可以在变量部分中找到。
| 响应吗 | 描述 |
|---|---|
201 |
表示已创建表单实例。 |
400 |
表示未找到表单定义(基于标识符或键),通过发送给定消息未存储表单实例,或者已传递无效变量。 状态描述包含有关错误的其他信息。 |
响应成功正文:
1
2
3
4
5
6
7
8
9
10
11
12
{
"id":"48b9ac82-f1d3-11e6-8549-acde48001122",
"url":"http://localhost:8182/form/form-instances/48b9ac82-f1d3-11e6-8549-acde48001122",
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"submittedDate":"2013-04-17T10:17:43.902+0000",
"submittedBy":"testUser",
"formValuesId":"818e4703-f1d2-11e6-8549-acde48001110",
"tenantId": null
}
7.4.3. 表单实例列表
GET form/form-instances
| 请求参数 | 是否必须 | 值类型 | 描述 |
|---|---|---|---|
id |
否 |
字符串 |
仅返回具有给定标识符的流程实例。 |
表单定义ID |
否 |
字符串 |
仅返回具有给定表单定义标识符的表单实例。 |
模糊匹配表单ID |
否 |
字符串 |
仅返回具有表单定义标识符(模糊匹配给定值)的表单实例。 |
任务ID |
否 |
字符串 |
仅返回具有给定任务标识符的表单实例。 |
模糊匹配任务ID |
否 |
字符串 |
仅返回具有任务标识符(如模糊匹配给定值)的表单实例。 |
流程实例ID |
否 |
字符串 |
仅返回具有给定流程实例标识符的表单实例。 |
模糊匹配表单实例ID |
否 |
字符串 |
仅返回具有与给定值(模糊匹配流程实例标识符)的表单实例。 |
流程定义ID |
否 |
字符串 |
仅返回具有给定流程定义标识符的表单实例。 |
模糊匹配流程定义ID |
否 |
字符串 |
仅返回具有与给定值(模糊匹配的流程定义标识符)的表单实例。 |
由…提交 |
否 |
字符串 |
仅返回由…提交的给定提交的表单实例。 |
模糊匹配由…提交 |
否 |
字符串 |
只返回模糊匹配给定值的提交的表单实例。 |
租户ID |
否 |
字符串 |
仅返回具有给定租户ID的流程实例。 |
模糊匹配租户ID |
否 |
字符串 |
仅返回具有类似给定值的(模糊匹配租户ID)的流程实例。 |
没有租户ID |
否 |
布尔 |
如果 true,则仅返回没有设置租户ID的流程实例。 如果是false,则忽略 租户ID 参数。 |
排序 |
否 |
字符串 |
排序字段,应该是 提交日期 (默认)或 租户ID。 一般分页和排序 查询参数可以用在本链接 |
| 响应编码 | 描述 |
|---|---|
200 |
表示请求成功,并返回表单实例 |
400 |
表示参数以错误的格式传递。 状态消息包含其他信息。 |
成功响应正文:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"data":[
{
"id":"48b9ac82-f1d3-11e6-8549-acde48001122",
"url":"http://localhost:8182/form/form-instances/48b9ac82-f1d3-11e6-8549-acde48001122",
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"submittedDate":"2013-04-17T10:17:43.902+0000",
"submittedBy":"testUser",
"formValuesId":"818e4703-f1d2-11e6-8549-acde48001110",
"tenantId": null
}
],
"total":1,
"start":0,
"sort":"submittedDate",
"order":"asc",
"size":1
}
7.4.4. 查询表单实例
POST query/form-instances
请求正文:
1
2
3
{
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122"
}
请求正文可以包含可以在查询流程实例列表中使用的所有可能的过滤器
普通 分页和排序,查询参数 可用于此URL。
| 响应编码 | 描述 |
|---|---|
200 |
表示请求成功,并返回表单实例 |
400 |
表示参数以错误的格式传递。 状态消息包含其他信息 |
成功响正文:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"data":[
{
"id":"48b9ac82-f1d3-11e6-8549-acde48001122",
"url":"http://localhost:8182/form/form-instances/48b9ac82-f1d3-11e6-8549-acde48001122",
"formDefinitionId":"818e4703-f1d2-11e6-8549-acde48001122",
"taskId":"88",
"processInstanceId":"66",
"processDefinitionId":"oneTaskProcess:1:158",
"submittedDate":"2013-04-17T10:17:43.902+0000",
"submittedBy":"testUser",
"formValuesId":"818e4703-f1d2-11e6-8549-acde48001110",
"tenantId": null
}
],
"total":1,
"start":0,
"sort":"submittedDate",
"order":"asc",
"size":1
}
7.5. 表单引擎
7.5.1. 获取表单引擎信息
GET form-management/engine
返回此REST服务中使用的引擎的只读视图。
成功响应正文:
1
2
3
4
5
6
{
"name":"default",
"version":"6.5.0.event-SNAPSHOT",
"resourceUrl":"file://flowable/flowable.form.cfg.xml",
"exception":null
}
| 响应编码 | 描述 |
|---|---|
200 |
表示返回表单引擎信息。 |