之前,我们已经分析了如何在页面对动态表单进行显示。表单显示出来了,那么接下来我们就需要将动态表单中的信息保存到数据库。
在此,我们再次明确一下动态表单的使用的条件:假设现在有多条流程,每一条流程都需要不同形式的表单。
这里,我们分成两大步:为该流程添加所需的动态表单和将动态表单中数据存储到数据库
首先,是页面一:用于显示已经添加的表单信息:添加的表单都会在这里进行以字符串的形式显示(见下图)
<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="#" onclick="del('flowform.do?command=delField&id=${field.id}')">删除</a> <a href="#" onclick="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)两个动态属性,在数据库的体现为(请大家结合第一篇介绍动态表单的类图,一起查看):
下面保存动态表单对应的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"); }
这样就将数据保存到数据库了。
假如对应添加姓名与年龄两个字段的动态属性,在数据库的体现是: