现在的位置: 首页 > 综合 > 正文

STRUTS实现多附件上传(转)

2013年09月01日 ⁄ 综合 ⁄ 共 3682字 ⁄ 字号 评论关闭

    struts的附件管理是通过org.apache.struts.upload.FormFile这个接口实现的,在通过ActionServlet及RequestProcessor中利用MultipartRequestHandler对其进行了封装解析。其后台也是通过ASF的commons-fileupload.jar包来实现的。其实我们也可以直接用这个包中的DiskFileUpload和FileItem等类来自行实现。

1、首先是ActionForm

public class AttachForm extends BaseForm {
private List attachFiles = new ArrayList();

public List getAttachFiles() {
return attachFiles;
}

public void setAttachFiles(List attachFiles) {
this.attachFiles = attachFiles;
}

public AttachFile getAttachFile(int index) {
// ActionServlet在populate form的时候调用getAttachFile
// 不过index的顺序具有不确定性, 经调试3个控件时顺序为2/0/1
// 因此不管顺序如何都先添加一个然后取最大的一个
this.attachFiles.add(new AttachFile());
return (AttachFile) this.attachFiles.get(this.attachFiles.size() - 1);
}

}

2、然后是AttachFile

非常简单,只是实现对FormFile的封装

public class AttachFile implements Serializable {
private FormFile file;

public FormFile getFile() {
return file;
}

public void setFile(FormFile file) {
this.file = file;
}

}

3、接着来看看jsp

    关键点一个是动态添加脚本,一个是迭代产生的file控件。这里没有用到恼人的nested标签,直接用的logic和html的更容易理解。

<script type=”text/javascript”>
function addAttach() {
var iNumOfFiles = 0;
var files = document.getElementsByTagName(”input”);
for (var i = 0; i < files.length; i++) {
if (files[i].type == “file”) iNumOfFiles ++;
}
var tbAttach = document.getElementById(”tbAttach”);
var trAttach = document.createElement(”<tr/>”);
tbAttach.tBodies[0].appendChild(trAttach);
var tdAttach = document.createElement(”<td/>”);
trAttach.appendChild(tdAttach);
var sHtml = “<input type=/”file/” name=/”attachFile[” + iNumOfFiles + “].file/” value=/”/”>”;
tdAttach.innerHTML = sHtml;
}

function saveAttach() {
var sURL = “&action=save”;
doAction(sURL);
}
</script>

<html:form method=”post” action=”/attachAction” enctype=”multipart/form-data”>
<div class=”divAction”>
<html:button property=”btnSave” value=”添加” onclick=”addAttach()” />
<html:button property=”btnSave” value=”保存” onclick=”saveAttach()” />
</div>
<TABLE border=”1″ width=”100%” id=”tbAttach”>
<TR>
<TD>选择文件</TD>
</TR>
<logic:iterate id=”attachFile” name=”attachForm” property=”attachFiles” indexId=”index”>
<TR>
<TD><html:file property=”file” name=”attachFile” indexed=”true” />
</TD>
</TR>
</logic:iterate>
</TABLE>
</html:form>

产生的HTML为:

<TABLE border=”1″ width=”100%” id=”tbAttach”>
<TR>
<TD>选择文件</TD>
</TR>
<TR>
<TD><input type=”file” name=”attachFile[0].file” value=”"></TD>
</TR>
</TABLE>

注意<html:file property=”file” name=”attachFile” indexed=”true” />的property和name属性。很明显,populate时是通过调用attachForm.getAttachFile(index).setFile来完成的。

4、最后看看Action,这里用的是DispathAction。

  在add()时可以通过attachForm.setAttachFiles()指定缺省的控件数量;在save()中保存附件到服务器上,这里时放到servletContext下的upload文件夹下。

/**
* 添加
*/
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
AttachForm attachForm = (AttachForm) form;
List attachFiles = new ArrayList();
for (int i = 0; i < 1; i ++) {
attachFiles.add(new AttachFile());
}
attachForm.setAttachFiles(attachFiles);
return mapping.findForward(”add”);
}

/**
* 保存
*/
public ActionForward save(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
AttachForm attachForm = (AttachForm) form;
List attachFiles = attachForm.getAttachFiles();
for (int i = 0; i < attachFiles.size(); i++) {
AttachFile attachFile = (AttachFile) attachFiles.get(i);
FormFile file = attachFile.getFile();
if (file != null) {
InputStream in = file.getInputStream();
String filePath = this.getServlet().getServletContext().getRealPath(”/”);
this.logger.info(”file path: ” + filePath + “upload//” + file.getFileName());
OutputStream out = new FileOutputStream(filePath + “//” + file.getFileName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.close();
in.close();
this.logger.info(”file size:” + file.getFileSize());
} else {
this.logger.info(”file is null”);
}
}
return mapping.findForward(”success”);
}

 类似的博文可以参见:http://blog.csdn.net/wts/archive/2006/03/20/630083.aspx

抱歉!评论已关闭.