最近在做项目时候要用到文件上传功能,于是在网上找了一下相关资料,有好多人都用开源的commons fileupload 来上传文件,于是也用这个工具来完成项目需求。结合网上资料及实际项目,做一点点总结,以备后用。
使用commons fileupload 需要注意下面几点 :
1. 在 jsp 页面的 form 要使用 html 本身的 <form> 标记,而不要使用第三方视图开源框架的 form 标记,例如不要使用 strut 的 <htm:form> 。
2. 在 <form> 的属性里必须加上 ENCTYPE = "multipart/form-data"
3. 在 <input type=”file”> 的表单项里必须要有 name=”” 这一属性值对。 commons fileUpload 只认 name ,不认 id 。
4. 在调用 FileItem 的 write 方法前必须保证文件的存放路径存在否则出现异常。 commons fileupload 不会自动为你建立不存在的目录。
5. 如果使用 struts ,那么处理上传文件的 action 不能与任何 form 绑定。即在 struts 配置文件不要为 action 加上 name 属性。
下面是一些代码实例:
1. Upload.jsp
< form action = "../commonUpload.do?action=uploadFile" method = "post" ENCTYPE="multipart/form-data" >
从这里选择文件:
< input type = "file" name="file1" >< br />
< input type = "file" name="file2" >< br />
<input type = "text" name = "text1" value = "test value" />
< input type = "submit" value = "submit" ></ input >
</ form >
注意不要漏掉红色字体部分。
2. 添加 action 配置
< action path = "/commonUpload"
type = "com.lbh.webtest.action.testupload.CommonUpload"
scope = "request"
validate = "false"
parameter = "action" >
</ action >
千万不要画蛇添足加上 name 属性,不然够你郁闷的。
3. CommonUpload.java
public class CommonUpload extends DispatchAction
{
public ActionForward uploadFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
// 上传目录
File uploadDir = new File( "d://111" );
if (!uploadDir.exists())
{
uploadDir.mkdirs();
}
String upPath = "d://111" + File. separator ;
DiskFileItemFactory fileFact = new DiskFileItemFactory();
// 设置最多只允许在内存中存储的数据 , 单位 : 字节
fileFact.setSizeThreshold(4096);
ServletFileUpload sfu = new ServletFileUpload(fileFact);
// 设置允许用户上传文件大小 , 单位 : 字节,这里设为 1M
sfu.setSizeMax(1 * 1024 * 1024);
List fileItems = sfu.parseRequest(request);
Iterator iter = fileItems.iterator();
String fileName = "" ;
while (iter.hasNext()) // 循环表单元素
{
FileItem item = (FileItem) iter.next();
if (item.isFormField()) // 一般表单元素
{
String formName = item.getFieldName(); // 表单元素名称
if (formName.equalsIgnoreCase( "text1" ))
{
String str = item.getString( "UTF-8" ); // 以指定的编码得到该表单元素的值
System. out .println( "value:" + str);
}
}
else
// 文件
{
fileName = item.getName(); // 文件域中选择的文件名
if (fileName != "" )
{
File savedFile = new File(upPath, fileName);
item.write(savedFile); // 写文件,即上传
}
}
}
return mapping.findForward( "success" );
}
}
注:
parseRequest(request) 方法只能得到<form> 内部的表单项,如果使用javascript 在action 中绑定了其他的参数,这些参数将不会出现在parseRequest 返回的集合。
通过FileItem 的getFiledName() 可以得到form 表单项的name 属性值,例如上面的程序,如果对每一个FileItem 对象取fileName ,将得到字符串”file1” 和”file2” 和”text1” 。 FileItem 的getName 属性何以取得<input type=”file”> 表单项中选中的路径以及名称,而非上传文件的表单项将得到null 。getString(“encoding”) 方法可以以指定的编码方式得到表单元素的值。