之前,我们已经分析了如何在页面对动态表单进行显示。表单显示出来了,那么接下来我们就需要将动态表单中的信息保存到数据库。
在此,我们再次明确一下动态表单的使用的条件:假设现在有多条流程,每一条流程都需要不同形式的表单。
这里,我们分成两大步:为该流程添加所需的动态表单和将动态表单中数据存储到数据库
1、为某项流程添加特定的动态表单,将表单保存到数据库
首先,是页面一:用于显示已经添加的表单信息:添加的表单都会在这里进行以字符串的形式显示(见下图)
<table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0">
<c:if test="${empty flowForm.template }">
<c:set var="tmp" value="document_form.ftl"/>
</c:if>
<c:if test="${!empty flowForm.template }">
<c:set var="tmp" value="${flowForm.template}"/>
</c:if>
<tr>
<td class="tdEditLabel" >表单模板</td>
<td class="tdEditContent"><input type="text" name="template" value="${tmp}">
</td>
<td class="tdEditLabel" ></td>
<td class="tdEditContent"></td>
</tr>
</table>
<c:if test="${!empty flowForm }">
<hr>
<table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0">
<tr bgcolor="#EFF3F7" class="TableBody1">
<td width="20%"><B>标签</B></td>
<td width="20%"><B>名称</B></td>
<td width="20%" ><B>类型</B></td>
<td width="20%"><B>输入形式</B></td>
<td width="20%"><B>操作</B></td>
</tr>
<c:forEach items="${flowForm.fields }" var="field">
<tr>
<td >${field.fieldLabel }</td>
<td >${field.fieldName }</td>
<td >${field.fieldType.name }</td>
<td >${field.fieldInput.name }</td>
<td>
<a href="#" οnclick="del('flowform.do?command=delField&id=${field.id}')">删除</a>
<a href="#" οnclick="openWin('flowform.do?command=addItemInput&id=${field.id }','additem',700,600)">条目</a>
</td>
</tr>
</c:forEach>
</table>
</c:if>
然后,页面二:输入域界面,页面一 点击添加,跳至界面二,添加信息后,页面二关闭,并将添加的表单信息显示在页面一(见下图)。
<table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0">
<tr>
<td class="tdEditLabel" >标签</td>
<td class="tdEditContent"><input type="text" name="fieldLabel">
</td>
<td class="tdEditLabel" >名称</td>
<td class="tdEditContent"><input type="text" name="fieldName"></td>
</tr>
<tr>
<td class="tdEditLabel" >类型</td>
<td class="tdEditContent">
<select name="fieldTypeId">
<c:forEach items="${fieldtypes }" var="ft">
<option value="${ft.id }">${ft.name }</option>
</c:forEach>
</select>
</td>
<td class="tdEditLabel" >输入形式</td>
<td class="tdEditContent">
<select name="fieldInputId">
<c:forEach items="${fieldinputs }" var="fi">
<option value="${fi.id }">${fi.name }</option>
</c:forEach>
</select>
</td>
</tr>
</table>
(这里,是将添加的动态表单要保存到数据库,与下面的将动态表单中内容保存到数据库要区分开)
这里我们添加姓名(name)和性别(age)两个动态属性,在数据库的体现为(请大家结合第一篇介绍动态表单的类图,一起查看):
2、将动态表单中数据存储到数据库
下面保存动态表单对应的Action的实现:
在这个Action里面,需要做的主要操作就是:ActionForm以Map形式获得页面页面动态表单中数据,按照表单定义对应的类型进行数据转换,然后再设置到document业务对象,最后再将document业务对象保存到数据库。
public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
DocumentActionForm daf = (DocumentActionForm)form;
Document document = new Document();
BeanUtils.copyProperties(document, daf);
//处理Map的数据
//将ActionForm中的Map的数据,按照表单定义对应的类型来进行转换,并设置到document对象即可
if(daf.getProps().isEmpty()){
document.setProps(null);
}else{
int workflowId = daf.getWorkflowId();
//流程对应的表单定义
FlowForm flowForm = formManager.findForm(workflowId);
if(flowForm == null){
document.setProps(null);
}else{
Map documentProps = new HashMap();
//拿到表单定义对应的所有的域定义
Set fields = flowForm.getFields();
//遍历域
for (Iterator iter = fields.iterator(); iter.hasNext();) {
FormField field = (FormField) iter.next();
String propertyName = field.getFieldName();
FieldType propertyType = field.getFieldType();
//根据表单的属性名称,从Map中将界面上传过来的原始值拿出来
Object source = daf.getProps().get(propertyName);
Object target = null;
if(source != null){
//对于输入的字符串
if(source instanceof String && !propertyType.getType().equals("java.io.File")){
Class targetClass = Class.forName(propertyType.getType());
//利用ConvertUtils工具,将从界面上传过来的字符串
//转换为FormFiled对应的FieldType所指定类型的对象
target = ConvertUtils.convert((String)source, targetClass);
}
//如果表单域是上传文件
if(propertyType.getType().equals("java.io.File")){
//注意:如果界面上传的是文件,struts可以自动转换为FormFile
//类型的对象!!!!
FormFile ff = (FormFile)source;
target = ff.getFileData();
}
//现在,需要将target的值赋予document对象
if(target == null){
throw new SystemException("无法处理输入的值!");
}
DocumentProperty dp = new DocumentProperty();
String type = propertyType.getType();
if(type.equals("java.io.File")){
dp.setJava_io_File((byte[])target);
}
if(type.equals("java.lang.Integer")){
dp.setJava_lang_Integer((Integer)target);
}
if(type.equals("java.lang.String")){
dp.setJava_lang_String((String)target);
}
/*
* 以下面形式
* key-->表单域名称, value-->对应Java类型
* 存入map
*/
documentProps.put(propertyName, dp);
}
}
//将documentProps对象赋予document对象的props属性
document.setProps(documentProps);
}
}
if(daf.getContentFile() != null){
document.setContent(daf.getContentFile().getFileData());
}
//将信息保存进数据库
documentManager.addDocument(document, daf.getWorkflowId(), currentUser(request).getId());
return mapping.findForward("pub_add_success");
}
这样就将数据保存到数据库了。
假如对应添加姓名与年龄两个字段的动态属性,在数据库的体现是: