网上很多人都在问 struts多附件上传的问题:
搜索到的答案其中有:
Form部分:
public class MultiUploadForm extends ActionForm {
private List myFiles;
public MultiUploadForm(){
myFiles = new ArrayList();
//为了能够在页面初始显示一个file
myFiles.add(new UploadFile());
}
public List getMyFiles() {
return myFiles;
}
//注意这个方法的定义
public UploadFile getUploadFile(int index) {
int size = myFiles.size();
if (index > size-1) {
for (int i=0;i<index-size+1;i++){
myFiles.add(new UploadFile());
}
}
return (UploadFile) myFiles.get(index);
}
public void setMyFiles(List myFiles) {
this.myFiles = myFiles;
}
}
Dataset部分:
public class UploadFile implements Serializable {
private FormFile file;
public FormFile getFile() {
System.out.println("run in uploadFile.getFile()");
return file;
}
public void setFile(FormFile file) {
this.file = file;
}
}
JSP部分:
<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested" %>
<html:html>
<head>
<title>
multiUploadDemo
</title>
</head>
<script language="javascript" type="">
var num = 0;
function addFile(){
var innerHTML = multiUploadForm.innerHTML;
var signal = "<TD id=tdTarget>";
var signalLen = signal.length;
var targetIndex = innerHTML.indexOf(signal);
var preHTML = innerHTML.substring(0,(targetIndex-6));
var subHTML = innerHTML.substring(targetIndex-6);
num++;
var insertHTML = "<TR><TD><input type=file name=uploadFile["+ num + "].file value=''></TD>";
innerHTML = preHTML + insertHTML + subHTML;
multiUploadForm.innerHTML = innerHTML;
//alert(multiUploadForm.innerHTML);
}
function upload(){
multiUploadForm.submit();
}
</script>
<body bgcolor="#ffffff">
<html:form method="post" action="/multiUploadAction.do" enctype="multipart/form-data">
<table border="1">
<TBODY>
<br><br>
this is file
<nested:iterate id="uploadFile" property="myFiles" name="multiUploadForm" indexId="index">
<nested:nest property="uploadFile">
<nested:file property="file" name="uploadFile" indexed="true"/>
</nested:nest>
</nested:iterate>
<TR>
<input type="button" name="btnAddFile" value="Add File" οnclick="addFile()"/>
<TR><TD id="tdTarget"></TD>
<input type="button" name="btnUpload" value="upload" οnclick="upload()">
</TBODY>
</table>
</html:form>
</body>
</html:html>
这样的方法我也用了很长时间,谢谢原作者的共享;
从jsp再看form定义,很难理解文件怎么付到arraylist变量中去的?
今天从基本的方式尝试去解决, 定义 FormFile[] 和 FormFile 的arraylist; 都会报数组越界的错误;
仔细看了好多遍原代码,原来 struts 的 form 属性付值用的是 BeanUtils 的方式;BeanUtils只是简单使用过,还不了解它的强大功能;看原代码
public void setIndexedProperty(Object bean, String name,
int index, Object value)
{.............
// Call the property getter to get the array or list
Object array = invokeMethod(readMethod, bean, new Object[0]);
if (!array.getClass().isArray()) {
if (array instanceof List) {
// Modify the specified value in the List
((List) array).set(index, value);
} else {
throw new IllegalArgumentException("Property '" + name +
"' is not indexed");
}
} else {
// Modify the specified value in the array
Array.set(array, index, value);
}
}
用的 list 的 set 方法,而不是add方法;所以出现了越界的错误;上面实现的 public UploadFile getUploadFile(int index) 方法的实现就是解决这个问题的;同时原作者利用了BeanUtils中NestedProperty的特点,从而成功组装form的。
但是,总是要定义一个新的类曾加一层逻辑,总感觉不舒服;所以我用继承ArrayList的方式实现不会越界的list
public class DynaSetArrayList extends ArrayList {
public Object set( int index, Object obj )
{
int size = size();
if( index > size-1)
{
for( int i=0; i< index-size+1; i++)
{
add( new Object());
}
}
Object old = get( index );
super.set( index, obj );
return old;
}
}
这样form 类只简单定义List attachs = new DynaSetArrayList();就可以了,比较简单。