activiti使用form表单引擎,生成form表单定义数据
项目地址:activiti-workflow
对于审批流,可以通过activiti的form引擎,定义表单信息。先设计表单信息,然后在设计流程时关联表单。
本文主要介绍在保存表单数据时踩过的坑,使用activiti的版本为6.0.0。
form表介绍:
- act_fo_form_definition :表单定义表
- act_fo_form_deployment:表单部署表
- act_fo_form_resource:表单源数据表
activiti提供了表单引擎的service,用于操作表单。表单数据的保存可以通过processEngine.getFormEngineRepositoryService().createDeployment().addFormDefinition(resourceName, formDefinition).name(formName).deploy();
当时开发时通过这种方式保存form表单数据,结果发现,只有act_fo_form_deployment和act_fo_form_resource两个表有数据,act_fo_form_definition 表没有数据。activiti提供的查询表单数的接口如图
要查出表单的定义数据,就要查询act_fo_form_definition ,现在这个表没有数据就会导致,表单数据可以保存进去,没法查出来。
后面跟了deploy的部署方法,在org.activiti.form.engine.impl.deployer.FormDeployer#deploy方法里
public void deploy(FormDeploymentEntity deployment) {
log.debug("Processing deployment {}", deployment.getName());
// The ParsedDeployment represents the deployment, the forms, and the form
// resource, parse, and model associated with each form.
//将表单定义数据封装为部署的数据,主要是这里的build方法
ParsedDeployment parsedDeployment = parsedDeploymentBuilderFactory.getBuilderForDeployment(deployment).build();
formDeploymentHelper.verifyFormsDoNotShareKeys(parsedDeployment.getAllForms());
formDeploymentHelper.copyDeploymentValuesToForms(parsedDeployment.getDeployment(), parsedDeployment.getAllForms());
formDeploymentHelper.setResourceNamesOnForms(parsedDeployment);
if (deployment.isNew()) {
Map<FormEntity, FormEntity> mapOfNewFormToPreviousVersion = getPreviousVersionsOfForms(parsedDeployment);
setFormVersionsAndIds(parsedDeployment, mapOfNewFormToPreviousVersion);
//插入表单定义数据
persistForms(parsedDeployment);
} else {
makeFormsConsistentWithPersistedVersions(parsedDeployment);
}
cachingAndArtifactsManager.updateCachingAndArtifacts(parsedDeployment);
}
跟进build方法,这里将ResourceEntity解析为FormEntity 并校验原文件名称的合法性即resourceName,这里如果校验不通过ParsedDeployment的forms属性就会为空。主要看isFormResource方法
public ParsedDeployment build() {
List<FormEntity> forms = new ArrayList<FormEntity>();
Map<FormEntity, FormParse> formToParseMap = new LinkedHashMap<FormEntity, FormParse>();
Map<FormEntity, ResourceEntity> formToResourceMap = new LinkedHashMap<FormEntity, ResourceEntity>();
for (ResourceEntity resource : deployment.getResources().values()) {
//校验文件名是否合法,合法后将ResourceEntity解析为FormEntity
if (isFormResource(resource.getName())) {
log.debug("Processing Form resource {}", resource.getName());
FormParse parse = createFormParseFromResource(resource);
for (FormEntity form : parse.getForms()) {
forms.add(form);
formToParseMap.put(form, parse);
formToResourceMap.put(form, resource);
}
}
}
return new ParsedDeployment(deployment, forms, formToParseMap, formToResourceMap);
}
isFormResource方法
protected boolean isFormResource(String resourceName) {
for (String suffix : FORM_RESOURCE_SUFFIXES) {
//校验resourceName的后缀是否是form
//这里的FORM_RESOURCE_SUFFIXES = new String[] { "form" };
if (resourceName.endsWith(suffix)) {
return true;
}
}
return false;
}
在看persistForms方法,ParsedDeployment 的forms不为空插入数据,在之前校验时,如果resourceName不合法,就没有将将ResourceEntity解析为FormEntity,forms为空,这里也就不会插入数据。
protected void persistForms(ParsedDeployment parsedDeployment) {
CommandContext commandContext = Context.getCommandContext();
FormEntityManager formEntityManager = commandContext.getFormEntityManager();
for (FormEntity form : parsedDeployment.getAllForms()) {
formEntityManager.insert(form);
}
}
到这里就清楚了,由于在调用processEngine.getFormEngineRepositoryService().createDeployment().addFormDefinition(resourceName, formDefinition).name(formName).deploy();
时resourceName的值是随便取了一个值,没有以form结尾,导致校验resourceName时不通过,就没有在定义表中插入数据。