添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

可以自行选择用于Flowable开发的IDE。如果想要使用Flowable Designer,则需要Eclipse Mars或Neon。 到 Eclipse下载页面 选择Eclipse版本并下载。解压下载的文件, 然后执行 eclipse 目录下的eclipse文件。手册后续有专门一章介绍如何 安装我们的Eclipse Designer插件

2.1. 创建一个DMN引擎 Creating a DMN Engine

Flowable DMN引擎的结构与Flowable流程引擎十分相似。因此,本文档的部分内容与流程引擎的对应部分也十分相似。

Flowable DMN引擎使用一个名为 flowable.dmn.cfg.xml 的XML文件配置。请注意在使用 Sping方式创建DMN引擎 的情况下不是这样。

得到 DmnEngine 最简单的方法,是使用 org.flowable.dmn.engine.DmnEngines 类:

默认情况下,每次流程引擎创建时会进行版本检查,通常是在你的应用或者Flowable web应用启动的时候。如果Flowable库发现库版本与Flowable数据库表版本不同,会抛出异常。

要进行升级,首先需要将下列配置参数放入你的flowable.dmn.cfg.xml配置文件:

9"statusCode":404,"errorMessage":"Could not find a decision table with key 'decision1'."
Rest URL查询参数 Rest URL query parameters

作为查询字符串添加在URL中的参数(例如http://host/flowable-rest/dmn-api/dmn-repository/deployments/?name=Deployment中的name参数)可以使用下列类型,也会在相应的REST-API文档中提到:

分页与排序 Paging and sorting

分页与排序参数可以作为查询字符串加入URL中(例如http://host/flowable-rest/dmn-api/dmn-repository/deployments?sort=name中的name参数)。

"id":"03ab310d-c1de-11e6-a4f4-62ce84ef239e","name":null,"deploymentTime":"2016-12-14T10:16:37.000+01:00","category":null,"url":"http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e","parentDeploymentId":"17510","tenantId":"""total":1,"start":0,"sort":"id","order":"asc","size":1"id":"03ab310d-c1de-11e6-a4f4-62ce84ef239e","name":null,"deploymentTime":"2016-12-14T10:16:37.000+01:00","category":null,"url":"http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e","parentDeploymentId":"17510","tenantId":"""id":"03ab310d-c1de-11e6-a4f4-62ce84ef239e","name":"newDeployment1","deploymentTime":"2016-12-14T10:16:37.000+01:00","category":null,"url":"http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e","tenantId":"myTenant""id":"46b0379c-c0a1-11e6-bc93-6ab56fad108a","url":"http://localhost:8080/flowable-rest/dmn-api/dmn-repository/decision-tables/46b0379c-c0a1-11e6-bc93-6ab56fad108a","category":null,"name":"Decision Table One","key":"DecisionTableOne","description":null,"version":3,"resourceName":"dmn-DecisionTableOne.dmn","deploymentId":"46aa6b3a-c0a1-11e6-bc93-6ab56fad108a","parentDeploymentId":"5001","tenantId":"""total":1,"start":0,"sort":"name","order":"asc","size":1"id":"46b0379c-c0a1-11e6-bc93-6ab56fad108a","url":"http://localhost:8080/flowable-rest/dmn-api/dmn-repository/decision-tables/46b0379c-c0a1-11e6-bc93-6ab56fad108a","category":null,"name":"Decision Table One","key":"DecisionTableOne","description":null,"version":3,"resourceName":"dmn-DecisionTableOne.dmn","deploymentId":"46aa6b3a-c0a1-11e6-bc93-6ab56fad108a","parentDeploymentId":"5001","tenantId":"""name":"The One Task Process","executable":true,"documentation":"One task process description",

请求体需要包含multipart/form-data类型的数据。需要提供decisionKey。可选提供tenantId和inputVariables(rest变量)的map。

"resultVariables":["name":"output1","type":"string","value":"was option two""url":"http://localhost:8080/flowable-rest/dmn-api/rules/decision-executor""name":"default","version":"6.0.1","resourceUrl":"file://flowable-dmn/flowable.dmn.cfg.xml","exception":null
1
DmnEngine dmnEngine = DMNEngines.getDefaultDmnEngine() 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="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration"> <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 DMN只能用于Spring环境!我们只是简单利用Spring内部的解析与依赖注入功能来构造引擎。

也可以通过编程方式使用配置文件,来构造DMNEngineConfiguration对象。也可以使用不同的bean id(例如第3行)。

6
DmnEngineConfiguration. createDmnEngineConfigurationFromResourceDefault(); createDmnEngineConfigurationFromResource(String resource); createDmnEngineConfigurationFromResource(String resource, String beanName); createDmnEngineConfigurationFromInputStream(InputStream inputStream); createDmnEngineConfigurationFromInputStream(InputStream inputStream, String beanName); 4DmnEngine dmnEngine = DmnEngineConfiguration.createStandaloneInMemDmnEngineConfiguration() .setDatabaseSchemaUpdate(DmnEngineConfiguration.DB_SCHEMA_UPDATE_FALSE) .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000") .buildDmnEngine();

org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration: 流程引擎独立运行。Flowable自行处理事务。在默认情况下,数据库检查只在引擎启动时进行(如果Flowable DMN表结构不存在或表结构版本不对,会抛出异常)。

org.flowable.dmn.engine.impl.cfg.StandaloneInMemDmnEngineConfiguration: 这是一个便于使用单元测试的类。Flowable DMN自行处理事务。默认使用H2内存数据库。数据库会在引擎启动时创建,并在引擎关闭时删除。使用这个类时,很可能不需要更多的配置。

org.flowable.dmn.spring.SpringDmnEngineConfiguration: 在流程引擎处于Spring环境时使用。查看Spring集成章节获得更多信息。

2.3. 插入流程引擎 Plug into Process Engine

除了在独立模式下运行之外,也可能需要将DMN引擎插入流程引擎中。这样可以使流程引擎能够使用DMN和其他引擎。这样就可以,例如,让流程引擎的部署服务API可以部署的包中,不止包含BPMN模型,还可以包含DMN模型。

要在流程引擎中使用DMN引擎,需要在流程引擎配置文件的configurators列表中,添加org.flowable.dmn.engine.configurator.DmnEngineConfigurator

20
<bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration"> <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="dmnEngineConfigurator" class="org.flowable.dmn.engine.configurator.DmnEngineConfigurator"> <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" /> </bean> <bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <property name="configurators"> <ref bean="dmnEngineConfigurator" /> </list> </property> </bean> 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="" /> 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="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration"> <property name="dataSource" ref="dataSource" />

databaseType: 通常不需要专门设置这个参数,因为它可以从数据库连接信息中自动检测得出。只有在自动检测失败时才需要设置。可用值:{h2, mysql, oracle, postgres, mssql, db2}。这个选项会决定创建、删除与查询时使用的脚本。查看“支持的数据库”章节了解我们支持哪些类型的数据库。

databaseSchemaUpdate: 用于设置流程引擎启动关闭时使用的数据库表结构控制策略。

false (默认): 当引擎启动时,检查数据库表结构的版本是否匹配库文件版本。版本不匹配时抛出异常。

true: 构建引擎时,检查并在需要时更新表结构。表结构不存在则会创建。

create-drop: 引擎创建时创建表结构,并在引擎关闭时删除表结构。

2.5. JNDI数据源配置 JNDI Datasource Configuration

默认情况下,Flowable DMN的数据库配置保存在每个web应用WEB-INF/classes目录下的db.properties文件中。有时这样并不合适,因为这需要用户修改Flowable源码中的db.properties文件并重新编译war包,或者在部署后解开war包并修改db.properties文件。

通过使用JNDI(Java Naming and Directory Interface,Java命名和目录接口)获取数据库连接时,连接就完全由Servlet容器管理,并可以在war部署之外管理配置。同时也提供了比db.properties中更多的控制连接的参数。

2.5.1. 配置 Configuration

根据你使用的servlet容器应用不同,配置JNDI数据源的方式也不同。下面的介绍用于Tomcat,对于其他容器应用,请参考对应的文档。

Tomcat的JNDI资源配置在$CATALINA_BASE/conf/[enginename]/[hostname]/[warname].xml (对于Flowable UI应用,通常会是$CATALINA_BASE/conf/Catalina/localhost/flowable-app.xml)。当应用第一次部署时,默认会从Flowable war包中复制context.xml。所以如果存在这个文件则需要替换。例如,如果需要将JNDI资源修改为应用连接MySQL而不是H2,按照下列修改文件:

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>

mysql

jdbc:mysql://localhost:3306/flowable_dmn?autoReconnect=true

已使用mysql-connector-java数据库驱动测试

oracle

jdbc:oracle:thin:@localhost:1521:xe

postgres

jdbc:postgresql://localhost:5432/flowable_dmn

jdbc:db2://localhost:50000/flowable_dmn

mssql

jdbc:sqlserver://localhost:1433;databaseName=flowable_dmn (jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver) jdbc:jtds:sqlserver://localhost:1433/flowable_dmn (jdbc.driver=net.sourceforge.jtds.jdbc.Driver)

已使用Microsoft JDBC Driver 4.0 (sqljdbc4.jar)与JTDS Driver测试

<beans > <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration"> <!-- ... --> <property name="databaseSchemaUpdate" value="true" /> <!-- ... --> </bean> </beans>

默认情况下,Flowable引擎依赖中不提供SFL4J绑定jar。你需要自行将其加入你的项目,以便使用所选的日志框架。如果没有加入实现jar,SLF4J会使用NOP-logger。这时除了一条警告外,不会记录任何日志。可以从http://www.slf4j.org/codes.html#StaticLoggerBinder了解关于绑定的更多信息。

可以像这样(这里使用Log4j)使用Maven添加依赖,请注意你还需要加上版本:

4
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency>

重要提示:当使用classpath中带有commons-logging的容器时:为了将spring的日志路由至SLF4j,需要使用桥接(参考http://www.slf4j.org/legacy.html#jclOverSLF4J)。如果你的容器提供了commons-logging实现,请按照http://www.slf4j.org/codes.html#release页面的指示来保证稳定性。

使用Maven的示例(省略了版本):

4
<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> 4DmnEngine dmnEngine = DmnEngines.getDefaultDmnEngine(); DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService(); DmnRepositoryService dmnRepositoryService = dmnEngine.getDmnRepositoryService(); DmnManagementService dmnManagementService = dmnEngine.getDmnManagementService();

DmnEngines.getDefaultDmnEngine()在第一次被调用时将初始化并构建DMN引擎,在之后的调用都会返回相同的DMN引擎。DMN引擎的创建通过DMNEngines.init()实现,关闭由DMNEngines.destroy()实现。

DmnEngines会扫描所有flowable.dmn.cfg.xmlflowable-dmn-context.xml文件。对于所有的flowable.dmn.cfg.xml文件,DMN引擎会以标准Flowable方式构建引擎:DmnEngineConfiguration.createDmnEngineConfigurationFromInputStream(inputStream).buildDmnEngine()。对于所有的flowable-dmn-context.xml文件,DMN引擎会以Spring的方式构建:首先构建Spring应用上下文,然后从该上下文中获取DMN引擎。

所有的服务都是无状态的。这意味着你可以很容易的在集群环境的多个节点上运行Flowable DMN,使用同一个数据库,而不用担心上一次调用实际在哪台机器上执行。不论在哪里执行,对任何服务的任何调用都是幂等(idempotent)的。

DmnRepositoryService很可能是使用Flowable DMN引擎要用的第一个服务。这个服务提供了管理与控制部署(deployments)DMN定义(DMN definitions)的操作。DMN定义是DMN模型的基础概念(DMN的主要概念在DMN介绍章节中介绍)。它包含了选择(decision)以及对应的选择表(decision table)部署(deployment)是Flowable DMN引擎中的包装单元,一个部署中可以包含多个DMN XML文件。部署意味着将它上传至引擎,引擎将在储存至数据库之前检查与分析所有的DMN定义。从这里开始,可以在系统中使用这个部署,部署中包含的所有选择都可以使用。

此外,这个服务还可以:

* 按照key查找并执行一个选择。 --Execute a decision identified by it's key. * @param decisionKey 选择的key,不能为null。 --the decision key, cannot be null * @param inputVariables 包含输入变量的map。 --map with input variables * @return 执行的{@link RuleEngineExecutionResult}。 --the {@link RuleEngineExecutionResult} for this execution * @throws FlowableObjectNotFoundException * 如果给定key不存在。 --when the decision with given key does not exist. * @throws FlowableException * 如果执行选择时发生错误。 --when an error occurs while executing the decision. RuleEngineExecutionResult executeDecisionByKey(String decisionKey, Map<String, Object> inputVariables);

在上例中,如果传递的key找不到选择,会抛出异常。并且,由于javadoc中明确要求decisionKey不能为null,因此如果传递了null值,会抛出FlowableIllegalArgumentException异常

尽管我们想避免过大的异常层次结构,在特定情况下仍然会抛出下述异常子类。所有流程执行与API调用中发生的错误,如果不符合下面列出的异常,会统一抛出FlowableExceptions

FlowableClassLoadingException: 当需要载入的类(如JavaDelegates, TaskListeners, …​)无法找到,或载入时发生错误时抛出。

FlowableObjectNotFoundException: 当请求或要操作的对象不存在时抛出。

FlowableIllegalArgumentException: 这个异常说明调用Flowable DMN API时使用了不合法的参数。可能是引擎配置中的不合法值,或者是API调用传递的不合法参数。

4
List<DmnDeployment> dmnDeployments = dmnRepositoryService.createDeploymentQuery() .deploymentNameLike("deployment%") .orderByDeployTime() .list(); 7long count = dmnRepositoryService.createNativeDeploymentQuery() .sql("SELECT count(*) FROM " + dmnManagementService.getTableName(DmnDeploymentEntity.class) + " D1, " + dmnManagementService.getTableName(DecisionTableEntity.class) + " D2 " + "WHERE D1.ID_ = D2.DEPLOYMENT_ID_ " + "AND D1.ID_ = #{deploymentId}") .parameter("deploymentId", deployment.getId()) .count();

Flowable支持JUnit V4的单元测试风格。撰写JUnit 4测试用例时,可以使用org.flowable.dmn.engine.test.FlowableDmnRule Rule。使用这个Rule,就可以通过getter访问DMN引擎和服务。引入这个Rule就可以使用org.flowable.dmn.engine.test.DmnDeploymentAnnotation注解(参见上例解释其用途及配置),并且会自动在classpath中寻找默认配置文件。当使用相同的配置资源时,流程引擎会静态缓存,以用于多个单元测试。也可以为Rule提供自定义的引擎配置。

下面的代码片段展示了JUnit 4风格的测试与FlowableDmnRule的用法(并传入了一个可选的自定义配置):

20
public class MyDecisionTableTest { @Rule public FlowableDmnRule flowableDmnRule = new FlowableDmnRule("custom1.flowable.dmn.cfg.xml"); @Test @DmnDeploymentAnnotation public void ruleUsageExample() { DmnEngine dmnEngine = flowableDmnRule.getDmnEngine(); DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService(); Map<String, Object> inputVariables = new HashMap<>(); inputVariables.put("inputVariable1", 2); inputVariables.put("inputVariable2", "test2" ); RuleEngineExecutionResult result = dmnRuleService.executeDecisionByKey("decision1", inputVariables); Assert.assertEquals("result2", result.getResultVariables().get("outputVariable1"));

3.5. Web应用中的DMN引擎 The DMN engine in a web application

DmnEngine是线程安全的类,可以很容易地在多个线程间共享。在web应用中,这意味着可以在容器启动时创建DMN引擎,并在容器关闭时关闭引擎。

下面的代码片段展示了如何在纯Servlet环境中,简单的通过ServletContextListener初始化与销毁流程引擎。

11
public class DmnEnginesServletContextListener implements ServletContextListener { public void contextInitialized(ServletContextEvent servletContextEvent) { DmnEngines.init(); public void contextDestroyed(ServletContextEvent servletContextEvent) { DmnEngines.destroy(); 7<bean id="dmnEngineConfiguration" class="org.flowable.dmn.spring.SpringDmnEngineConfiguration"> </bean> <bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean"> <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" /> </bean>

4.2. 自动部署资源 Automatic resource deployment

集成Spring还提供了部署资源的特殊方式。在DMN引擎配置中,可以指定一组资源。当DMN引擎被创建时,这些资源都会被扫描并部署。有过滤器用于阻止重复部署。只有当资源确实发生变化时,才会重新部署至Flowable DMN数据库。在Spring容器经常重启(例如测试时)的时候,这很有用。

这里有个例子:

9
<bean id="dmnEngineConfiguration" class="org.flowable.spring.SpringDmnEngineConfiguration"> <property name="deploymentResources" value="classpath*:/org/flowable/spring/test/autodeployment/autodeploy/decision*.dmn" /> </bean> <bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean"> <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" /> </bean>

默认情况下,这个配置会将符合这个过滤器的所有资源组织在一起,作为Flowable DMN引擎的一个部署。重复检测过滤器将作用于整个部署,避免重复地部署未改变资源。有时这不是你想要的。例如,如果用这种方式部署了一组DMN资源,即使只有其中的一个资源发生了改变,整个部署都会被认为已经改变,因此这个部署中所有的所有DMN定义都会被重新部署。这将导致每个DMN定义都会刷新版本号,即使实际上只有一个DMN发生了变化。

可以使用SpringDmnEngineConfiguration中的额外参数deploymentMode,定制部署的选择方式。这个参数定义了在一组符合过滤器的资源中,组织部署的方式。默认这个参数有3个可用值:

single-resource: 为每个资源创建一个单独的部署,并用于重复检测过滤。当你希望单独部署每一个DMN定义,并且在它发生变化时创建新的DMN定义版本,应该使用这个值。

resource-parent-folder: 为同一个目录下的资源创建一个单独的部署,并用于重复检测过滤。这个参数值可以为大多数资源创建独立的部署。同时仍可以通过将部分资源放在同一个目录下,将它们组织在一起。这里有一个将deploymentMode设置为single-resource的例子:

6
<bean id="dmnEngineConfiguration" class="org.flowable.dmn.spring.SpringDmnEngineConfiguration"> <property name="deploymentResources" value="classpath*:/flowable/*.dmn" /> <property name="deploymentMode" value="single-resource" /> </bean> 25@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:org/flowable/spring/test/junit4/springTypicalUsageTest-context.xml") public class SpringJunit4Test { @Autowired private DmnEngine dmnEngine; @Autowired private DmnRuleService ruleService; @Autowired @Rule public FlowableDmnRule flowableSpringRule; @Test @DmnDeploymentAnnotation public void simpleDecisionTest() { Map<String, Object> inputVariables = new HashMap<>(); inputVariables.put("input1", "testString"); RuleEngineExecutionResult executionResult = ruleService.executeDecisionByKey("decision1", inputVariables); assertEquals("test1", executionResult.getResultVariables().get("output1")); 3<bean id="flowableDmnRule" class="org.flowable.dmn.engine.test.FlowableDmnRule"> <property name="dmnEngine" ref="dmnEngine"/> </bean> 7String dmnDefinition = "path/to/definition-one.dmn"; ZipInputStream inputStream = new ZipInputStream(new FileInputStream(barFileName)); repositoryService.createDeployment() .name("definition-one") .addClasspathResource(dmnDefinition) .deploy();

5.2. DMN选择的版本 Versioning of DMN decisions

DMN并没有版本的概念。这其实很好,因为可执行的DMN定义文件很可能已经作为你的开发项目的一部分,保存在版本管理系统仓库中了(例如Subversion,Git,或者Mercurial)。在部署时,会创建DMN定义的版本。在部署时,Flowable会在保存至Flowable数据库前,为decision指定版本。

对于DMN定义中的每个DMN选择,下列步骤都会执行,以初始化keyversionnameid参数:

4
<definitions id="myDefinitions" > <decision id="myDecision" name="My important decision" > <decisionTable id="decisionTable1" hitPolicy="FIRST" > 4<definitions id="myNewDefinitions" > <decision id="myNewDecision" name="My important decision" > <decisionTable id="decisionTable1" hitPolicy="FIRST" > 13<definitions xmlns="http://www.omg.org/spec/DMN/20151101" namespace="http://www.flowable.org/dmn" name="DetermineDiscount"> <decision id="DET_DISC_1" name="DetermineDiscount"> <decisionTable id="determineDiscountTable1" hitPolicy="FIRST"> </decisionTable> </decision> </definitions>

6.3. 创建一个DMN定义 Creating a DMN definition

可以使用文本编辑器创建DMN定义。但是在这个例子中,我们使用Flowable modeler中提供的选择表编辑器创建。

我们将实现一个非常简单的用例:根据用户分类,决定折扣比例。

在Flowable modeler中打开选择表界面。

44
<definitions xmlns="http://www.omg.org/spec/DMN/20151101" id="definition_052249e2-f35d-11e6-9c45-0242ac120005" name="Determine Discount" namespace="http://www.flowable.org/dmn"> <decision id="DET_DISC_1" name="Determine Discount"> <decisionTable id="decisionTable_052249e2-f35d-11e6-9c45-0242ac120005" hitPolicy="FIRST"> <input label="Customer Category"> <inputExpression id="inputExpression_5"> <text>customercat</text> </inputExpression> </input> <output id="outputExpression_6" label="Discount Percentage" name="discountperc" typeRef="number"></output> <inputEntry id="inputEntry_5_1"> <text>== "BRONZE"</text> </inputEntry> <outputEntry id="outputEntry_6_1"> <text>5</text> </outputEntry> </rule> <inputEntry id="inputEntry_5_2"> <text>== "SILVER"</text> </inputEntry> <outputEntry id="outputEntry_6_2"> <text>10</text> </outputEntry> </rule> <inputEntry id="inputEntry_5_3"> <text>== "GOLD"</text> </inputEntry> <outputEntry id="outputEntry_6_3"> <text>20</text> </outputEntry> </rule> <inputEntry id="inputEntry_5_4"> <text></text> </inputEntry> <outputEntry id="outputEntry_6_4"> <text>0</text> </outputEntry> </rule> </decisionTable> </decision> </definitions>

7.1. Flowable DMN REST一般原则 General Flowable DMN REST principles

7.1.1. 安装与认证 Installation and Authentication

Flowable DMN在DMN引擎中包含了REST API,可以通过在servlet容器如Apache Tomcat中,部署flowable-app-rest.war文件来安装。但是也可以在其他的web应用中使用,只要在你的应用中包含这些servlet及其mapping,并在classpath中添加所有flowable-dmn-rest模块的依赖即可。

默认情况下Flowable DMN引擎连接至一个H2内存数据库。可以修改WEB-INF/classes文件夹下的db.properties文件中的数据库设置。DMN REST API使用JSON格式 (http://www.json.org) ,基于Spring MVC (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html) 构建。

默认情况下,所有REST资源都需要有一个有效的Flowable已认证用户。我们使用基础HTTP访问认证。因此在请求时,可以在HTTP头添加 Authorization: BasicXXX== ,也可以在请求url中包含用户名与密码(例如http://username:password@localhost:8080/xyz)。

建议使用基础认证时,同时使用HTTPS。

7.1.2. 配置 Configuration

Flowable REST web应用(flowable-app-rest)使用Spring Java Configuration来启动Flowable引擎、定义基础认证安全使用Spring security,以及为特定的变量处理定义变量转换。可以修改WEB-INF/classes目录下的engine.properties文件,定义少量参数。如果需要高级配置选项,可以在flowable-custom-context.xml文件中覆盖默认的Spring bean,这个文件也在WEB-INF/classes目录下。该文件中已经以注释形式提供了示例配置。也可以在这里重载默认的RestResponseFactories。对于DMN引擎来说,就是定义一个新的命名为dmnResponsefactory的Spring bean,使用自定义实现类。

7.1.3. 在Tomcat中使用 Usage in Tomcat

由于Tomcat中的默认安全参数默认不能使用已转义斜线符(%2F%5C)(返回400结果)。这可能会影响部署资源与其数据URL,因为URL可能隐含已转义斜线符。

当发现非预期的400结果时,设置下列系统参数:

-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

最佳实践是(post/put JSON时),在下面描述的HTTP请求中,永远将AcceptContent-Type头设置为application/json

7.1.4. 方法与返回码 Methods and return-codes

Table 1. HTTP方法与相应操作 Table 3. URL查询参数类型

String

纯文本参数。可以包含任何URL允许的合法字符。对于XXXLike参数,字符串可能会包含通配符%(需要进行URL编码)。可以进行like搜索,例如,'Tas%'将匹配所有以’Tas’开头的值。

Integer

整形参数。只能包含数字型非十进制值(原文如此,下同),在-2.147.483.648至2.147.483.647之间。

长整形参数。只能包含数字型非十进制值,在-9.223.372.036.854.775.808至9.223.372.036.854.775.807之间。

Boolean

boolean型参数。可以为truefalse。任何其他值都会导致'405 - 错误请求'响应。

日期型参数。使用ISO-8601日期格式(参考wikipedia中的ISO-8601),使用时间与日期部分(例如2013-04-03T23:45Z)。

Table 5. 查询变量参数

operator

查询使用的操作,可以为下列值:equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, lessThan, greaterThan, lessThanOrEquals, greaterThanOrEqualslike

所用变量的类型。当省略时,会从value参数推理类型。任何JSON文本值都认为是string类型,JSON boolean值认为是boolean类型,JSON数字认为是longinteger,取决于数字的大小。建议在有疑惑时明确指定类型。其他支持的类型列在下面。

scope

变量的范围。如果值为'local,则变量明确定义在其请求的资源上。如果值为global',则变量定义在其父上(或者父树中的任意父)。当写入变量且省略了scope时,使用global

变量的类型。查看下面的表格了解类型的更多信息。当写入变量且省略了这个值时,将使用请求的原始JSON属性类型推断,限制在string, double, integerboolean中。建议总是包含类型,以确保不会错误推断类型。