看到局部刷新,大家联想到的肯定是Ajax,但实际上,Ajax是没有办法实现文件上传的局部刷新的。由于安全性的需要,JavaScript代码是不能访问客户端文件系统,所以通过XMLHttpRequest的请求参数是无法得到上传文件的内容的,只能得到文件名。
那么我们又是怎样实现文件上传局部刷新的呢?其实我们再上传文件的时候采用的还是同步方式,为了不刷新整个页面,我们需要用到隐藏的iframe,我们在页面上增加一个隐藏的<iframe>元素,该元素将会作为提交表单的target。
文件上传要求表单的提交方式是POST,另外需要设置表单的MIME编码enctype="multipart/form-data"。页面代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>upload</title> </head> <body> <form action="UploadServlet" method="post" enctype="multipart/form-data" target="hideframe"> <input type="file" name="file"/> <input type="submit" value="上传"/> </form> <iframe name="hideframe" style="display:none"></iframe> </body> </html>
表单的target属性对应与<iframe>的name属性,这样就能够只更新<iframe>元素,从而实现无刷新的文件上传。
上传文件用到一个开源项目:commons-fileupload,将其添加到应用的WEB-INF/lib路径下即可。上传的Servlet代码如下:
public class UploadServlet extends HttpServlet {
/**
* 上传文件
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 解析器
ServletFileUpload sfu = new ServletFileUpload(factory);
// 解析,得到List
try {
List<FileItem> list = sfu.parseRequest(request);
FileItem fi = list.get(0);
//得到文件保存的路径
String fileName = fi.getName();//获取上传的文件名称
String root = this.getServletContext().getRealPath("files/upload/");
//创建文件
File destFile = new File(root, fileName);
//写数据
fi.write(destFile);
out.write("<script type='text/javascript'> alert('文件上传成功') </script>");
} catch (FileUploadException e) {
e.printStackTrace();
out.write("<script type='text/javascript'> alert('文件上传不成功,请重试') </script>");
}
}
}
例子写得比较简单,在实际上传处理中,FileItem还有以下常用方法
boolean isFormField():是否为普通表单项!返回true为普通表单项,如果为false即文件表单项;
String getFieldName():返回当前表单项的名称;
String getString(String charset):返回表单项的值;
long getSize():返回上传文件的字节数;
InputStream getInputStream():返回上传文件对应的输入流
要注意一点,request.getParametere("xxx")这个方法在表单为enctype="multipart/form-data"时作废,它只会返回null。所以要得到普通表单项的值,要使用上面说到的getString(String charset)方法。
Author:立礼
Sign:人生不要有太多的幻想,而要有更多的行动。
原文地址:http://blog.csdn.net/lzgs_4/article/details/45622787