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時不通過,就沒有在定義表中插入數據。