工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染

Activiti中的表单
- Activiti提供了一种方便而且灵活的方式在业务流程中以手工方式添加表单
- 对表单的支持有2种方式:
- 通过表单属性对内置表单进行渲染
- 通过表单属性对外置表单进行渲染
表单属性
- 业务流程相关联的所有信息:
- 包含自身的流程变量
- 通过流程变量的引用
- Activiti支持存储复杂的Java对象作为流程变量:
- 序列化对象
- Jpa实体对象
- 整个XML文档作为字符串
- 用户是在启动一个流程和完成用户任务时,与流程进行交互
- 表单需要某个UI技术渲染之后才能够与用户进行交互
- 为了能够使用不同UI技术变得容易,流程定义包含一个对流程变量中复杂的Java类型对象到一个properties的Map<String,String> 类型的转换逻辑
- 使用Activiti API的方法查看公开的属性信息.然后,任意UI技术都能够在这些属性上面构建一个表单.该属性专门为流程变量提供了一个视图. 表单所需要显示的属性可以返回值FormData中获取:
StartFormData FormService.getStartFormData(String processDefinitionId)
或者
TaskFormdata FormService.getTaskFormData(String taskId)
- 在默认情况下,内置的表单引擎遇到这些变量就像对待流程变量一样.如果任务表单属性和流程变量是一对一的关系,那么任务表单属性就不需要进行申明了:
<startEvent id="start" />
- 当执行到开始事件时,所有的流程变量都是可用的,但是
formService.getStartFormData(String processDefinitionId).getFormProperties()
会是一个空值,因为没有定义一个具体的映射
- 表单中所有被提交的属性都将会作为流程变量被存储在Activiti使用的数据库中. 这意味着在一个表单中新添加一个简单的input输入字段,也会作为一个新的变量被存储
- 属性来自于流程变量,但是不一定非要作为流程变量存储:
- 一个流程变量可能是JPA实体如类Address.在某种UI技术中使用的表单属性StreetName可能会关联到一个表达式 #{address.street}
- 用户提交的表单属性应该作为流程变量进行存储
- 使用UEL值表达式将其作为流程变量的一个嵌套属性进行存储
- 提交的表单属性默认的行为是作为流程变量进行存储,除非一个 formProperty 申明了其他的规则
- 类型转换也可以应用于表单数据和流程变量之间的处理:
<userTask id="task">
<extensionElements>
<activiti:formProperty id="room" />
<activiti:formProperty id="duration" type="long"/>
<activiti:formProperty id="speaker" variable="SpeakerName" writable="false" />
<activiti:formProperty id="street" expression="#{address.street}" required="true" />
</extensionElements>
</userTask>
- 表单属性room将会被映射为String类型流程变量room
- 表单属性duration将会被映射为java.lang.Long类型流程变量duration
- 表单属性speaker将会被映射为流程变量SpeakerName:
- writable="false" 只能够在TaskFormData对象中使用.如果属性speaker提交,将会抛出一个ActivitiException的异常
- readable="false" 该属性就会在FormData进行排除,但是在提交后仍然会对其进行处理
- 表单属性street将会映射为Java Bean address的属性street作为String类型的流程变量:
- 当提交的表单属性并没有提供并且required="true" 时,那么就会抛出一个异常
- 表单数据也可以作为FormData的一部分提供类型元数据.该FormData可以从以下方法的返回值中获取:
StartFormData FormService.getStartFormData(String processDefinitionId)
TaskFormdata FormService.getTaskFormData(String taskId)
- 表单属性类型:
- string: org.activiti.engine.impl.form.StringFormType
- long: org.activiti.engine.impl.form.LongFormType
- enum: org.activiti.engine.impl.form.EnumFormType
- date: org.activiti.engine.impl.form.DateFormType
- boolean: org.activiti.engine.impl.form.BooleanFormType
- 对于声明每一个表单属性,FormProperty信息可以通过以下方式获取:
List<FormProperty> formService.getStartFormData(String processDefinitionId).getFormProperties()
或者
List<FormProperty> formService.getTaskFormData(String taskId).getFormProperties()
public interface FormProperty {
/**
the key used to submit the property in {@link FormService#submitStartFormData(String, java.util.Map)}
* or {@link FormService#submitTaskFormData(String, java.util.Map)} */
String getId();
/** the display label */
String getName();
/** one of the types defined in this interface like e.g. {@link #TYPE_STRING} */
FormType getType();
/** optional value that should be used to display in this property */
String getValue();
/** is this property read to be displayed in the form and made accessible with the methods
* {@link FormService#getStartFormData(String)} and {@link FormService#getTaskFormData(String)}. */
boolean isReadable();
/** is this property expected when a user submits the form? */
boolean isWritable();
/** is this property a required input field */
boolean isRequired();
}
- 示例:
<startEvent id="start">
<extensionElements>
<activiti:formProperty id="speaker"
name="Speaker"
variable="SpeakerName"
type="string" />
<activiti:formProperty id="start"
type="date"
datePattern="dd-MMM-yyyy" />
<activiti:formProperty id="direction" type="enum">
<activiti:value id="left" name="Go Left" />
<activiti:value id="right" name="Go Right" />
<activiti:value id="up" name="Go Up" />
<activiti:value id="down" name="Go Down" />
</activiti:formProperty>
</extensionElements>
</startEvent>
- 所有的表单属性的信息都是可以通过API进行访问的:
- formProperty.getType().getName(): 获取类型的名称
- formProperty.getType().getInformation("datePattern"): 获取日期的匹配方式
- formProperty.getType().getInformation("values"): 可以获取到枚举值
- Activiti控制台支持表单属性并且可以根据表单定义对表单进行渲染:
<startEvent ... >
<extensionElements>
<activiti:formProperty id="numberOfDays" name="Number of days" value="${numberOfDays}" type="long" required="true"/>
<activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" value="${startDate}" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" />
<activiti:formProperty id="vacationMotivation" name="Motivation" value="${vacationMotivation}" type="string" />
</extensionElements>
</userTask>
当使用Activiti控制台时,会被渲染成流程的启动表单
外置表单的渲染
- Activiti中的API允许执行Activiti流程引擎之外的方式渲染任务表单,可以用自定义方式对任务表单进行渲染
- 所有需要渲染的表单属性进行装配的服务方法有两种:
- StartFormData FormService.getStartFormData(String processDefinitionId)
- TaskFormdata FormService.getTaskFormData(String taskId)
- 表单属性提交的两种方式:
- ProcessInstance FormService.submitStartFormData(String processDefinitionId, Map<String,String> properties)
- void FormService.submitStartFormData(String taskId, Map<String,String> properties)
- 可以将任何表单模版资源放进要部署的业务文档之中(如果想要按照流程的版本进行存储).将会在部署中作为一种可用的资源
- 获取部署表单模版的方式有两种:
- String ProcessDefinition.getDeploymentId()
- InputStream RepositoryService.getResourceAsStream(String deploymentId, String resourceName)
- 这样就可以获取表单模版定义文件,就可以在应用中渲染或者显示表单
- 也可以使用该功能获取任务表单之外的其他的部署资源用于其他的目的
- 属性 <userTask activiti:formKey="..." 暴露方式API:
- String FormService.getStartFormData(String processDefinitionId).getFormKey()
- String FormService.getTaskFormData(String taskId).getFormKey()
- 可以使用这个存储部署的模版中的全名(例如org/activiti/example/form/my-custom-form.xml) 但是这并不是必须的:
- 可以在表单属性中存储一个通用的key,然后运用一种算法或者换转去得到你实际使用的模版
- 当需要通过不同UI技术渲染不同的表单会更加方便:
- 使用正常屏幕大小的web应用程序的表单
- 移动手机小屏幕的表单
- IM表单
- email表单模版
工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染的更多相关文章
- 29 内置方法 eval | exec 元类 单例
eval与exec内置方法 将字符串作为执行目标,得到响应结果 eval常用作类型转换:该函数执行完有返回值 exec拥有执行更复杂的字符串:可以形成名称空间 eval内置函数的使用场景: 1.执 ...
- 工作流Activiti框架中的LDAP组件使用详解!实现对工作流目录信息的分布式访问及访问控制
Activiti集成LDAP简介 企业在LDAP系统中保存了用户和群组信息,Activiti提供了一种解决方案,通过简单的配置就可以让activit连接LDAP 用法 要想在项目中集成LDAP,需要在 ...
- 【应用篇】Activiti外置表单实例demo(四)
在这里我想说的外置表单.是说我们将我们自己的jsp(.form,.html)等页面上传到工作流的数据库中,当任务运行到当前结点时.给我们像前台发送绑定好的表单. 此处是给表单绑定表单的过程 water ...
- 工作流中的流程追溯!详细解析Activiti框架中的历史组件
Activit中的历史简介 历史: Activiti中的一个组件,可以捕获发生在进程执行中的信息并永久的保存.与运行时数据不同的是,当流程实例运行完成之后它还会存在于数据库中 历史实体对象有5个: H ...
- 工作流引擎Activiti使用进阶!详细解析工作流框架中高级功能的使用示例
Activiti高级功能简介 Activit的高级用例,会超越BPMN 2.0流程的范畴,使用Activiti高级功能需要有Activiti开发的明确目标和足够的Activiti开发经验 监听流程解析 ...
- activiti框架 数据库设计说明
1.结构设计 1.1. 逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...
- Activiti 框架学习
1:工作流的概念 说明: 1) 假设:这两张图就是华谊兄弟的请假流程图 2) 图的组成部分: 人物:范冰冰 冯小刚 王中军 事件(动作):请假.批准.不批准 工作流(Workflo ...
- Django.template框架 template context (非常详细)
前面的章节我们看到如何在视图中返回HTML,但是HTML是硬编码在Python代码中的 这会导致几个问题: 1,显然,任何页面的改动会牵扯到Python代码的改动 网站的设计改动会比Python代码改 ...
- OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据
OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据 我们这片博文就来聊聊这个反响很不错的OkHttp了,标题是我恶搞的,本篇将着重详细的 ...
随机推荐
- Vue和Node.js交互之token
博主最近工作的时候,公司后台使用的JAVA,在做登陆时总会传来一个token然后我存在了本地存储中或Vuex中,之后每一次请求把它带在请求头上,然后就好奇想要自己做一个后台服务器然后做一个完整的登陆的 ...
- mvnw 找不到或无法加载主类,找不到符号,类
如果你出现"找不到或无法加载主类"的问题,很有可能是maven的问题,你可以尝试一下这种办法: 问题:关于maven什么东西都没动,上午可能运行都好好的,下午可能就出现了这个问题, ...
- 利用主机域名配置Apache的虚拟主机功能
利用主机域名配置Apache的虚拟主机功能,可以减轻服务器为每一个网站分配IP地址的压力.而且根据不同的主机域名可以输出不同的网页内容.要实现此项功能,可以通过修改/etc/host文件来强制定义IP ...
- vue 进阶学习(一): vue 框架说明和与其他框架的对比
vue 框架说明和与其他框架的对比 一.说明 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与第三 ...
- 2020北航OO第三单元总结
2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...
- 还在一个模块打天下嘛?你知道引入Jetpack架构后,你的App会发生哪些奇妙的变化吗?
前言 上篇文章我给大家分享了我对Android架构的理解,从思想层面去讲述架构的演进过程.很多小伙伴读完后拍手叫好,表示还想听我讲一下对Jetpack 架构的看法,本着帮人帮到底的精神,今天我将再次动 ...
- 手撸了一个starter,同事直夸我666~
Spring Boot starter原理 Spring Boot 将常见的开发功能,分成了一个个的starter,这样我们开发功能的时候只需要引入对应的starter,而不需要去引入一堆依赖了!st ...
- linux中定时运行php(每分钟执行一次为例)
注:使用Crontab定时执行php脚本文件 1. 安装crontab yum install crontabs 说明:/sbin/service crond start //启动服务/sbin/se ...
- 接口测试原理及Postman详解
接口测试定义 接口是前后端沟通的桥梁,是数据传输的通道,包括外部接口.内部接口.内部接口又包括:上层服务与下层服务接口,同级接口 生活中常见接口:电脑上的键盘.USB接口,电梯按钮,KFC下单 接口测 ...
- 一道codeforces题目引发的差分学习
Codeforces Round #688 (Div. 2) 题目:B. Suffix Operations 题意:给定一个长为n的数组a,你可以进行两种操作:1).后缀+1; 2)后缀-1: ...