apache文件上传组件

来源:互联网 发布:西安交大远程网络教育 编辑:程序博客网 时间:2024/05/21 22:44

1 获取上传组件

使用Apache Commons Fileupload 文件上传组件需要两个类库文件:

1) commons-fileupload-1.2.2.jar

2) commons-io-1.4.jar

第一步:下载commons-fileupload-1.2.2.jar

在浏览器中输入http://commons.apache.org/fileupload/ 打开Apache Commons Fileupload 文件上传组件主页面,在 Downloading 栏目中点击任意一个版本号后面的“here”超级链接,可以打开当前最新版本的 Apache Commons Fileupload 文件上传组件下载页面,(2010-08-28为止的可下载最新版本是1.2.2版)。也可以直接输入http://commons.apache.org/fileupload/download_fileupload.cgi 打开最新版本下载页面。


在当前最新版本的下载页面,提供二进制可执行版本(Binares)和源程序版本(Source)两种文件的下载,每一种文件都有两种压缩格式:

1) .zip,适用windows 操作系统

2) .tar.gz,适用 linux 和 unix 操作系统

我们这里选择下载 commons-fileupload-1.3.3-bin.zip 文件。解压后得到如下目录结构:

commons-fileupload-1.3.3 (根目录)

----- commons-fileupload-1.3.3.jar (我们要用的二进制类库)

-----site (包括Apache Commons Fileupload 组件站点所有页面文件)

    ----- apidocs API文档目录,API文档链接可以在下面的首页中找到,也可以直接打开此目录,点击index.html打开API文档)

    ----- index.html(站点首页)

第二步:下载commons-io-1.4.jar

在浏览器中输入http://commons.apache.org/io/ 打开 Apache Commons IO 的主页,点击左侧菜单选项中的 Download 超级链接,打开当前最新版本下载页面(http://commons.apache.org/io/download_io.cgi),选择下载 commons-io-1.4-bin.zip 文件,解压缩在根目录中即可得到 commons-io-1.4.jar 。

到这里,我们就准备好了文件上传所需要的需要类库文件了。

一般在用Servlet处理表单元素时,表单元素都是一些简单的文本,Servlet很容易用Request.getParameter()就可以处理。但是当表单不止包含一些简单的文本,比如有上传文件域时,Servlet直接从HttpServletRequest对象中解析出复合表单的每一个子部分仍然是一项非常复杂的工作.

用户在客户端提交请求的方式:

有两种方式的POST方式请求:
  1)Content-Type的值为:application/x-www-form-urlencoded
  该方式提交普通表单组件,对应file组件只提交文件名----默认
  2)Content-Type的值为:multipart/form-date
  改方式可以提交帮普通表单组件和file组件,对于file组件不仅提交文件名,还提交文件内容数据流,
  如果表单中包含file组件,必须使用该方式提交,否则不会上传文件内容数据流

<form action="upload" method="post" enctype="multipart/form-data">    文件:<input type="file" name="file"/><br/>    文件说明:<input type="text" name="desc" /><br/>    <input type="submit" value="提交">    </form>
upload

package cn.hncu.servlet;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.util.List;import java.util.UUID;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.ProgressListener;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.commons.io.FileUtils;public class UploadServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//防止用户在地址栏,以get方式提交请求。response.setContentType("text/html;charset=utf-8");PrintWriter pw = response.getWriter();pw.println("文件上传出来不支持get方式提交");pw.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();request.setCharacterEncoding("utf-8");  //只对上传的文件名有效,对普通表单的编码无效//防黑2:防止用户以POST1的方式请求//法1:手动利用底层原理来实现//String type=request.getContentType();//if(!type.contains("multipart/form-date")){//out.println("文件上传不支持POST1方式提交");//}//法2:用apache文件上传工具提供的功能来实现//获取src下的目录--ClassLoader   获取WebRoot下的目录---ServletContextString path=getServletContext().getRealPath("/uploads");File dir=new File("e:/a");//临时文件存放目录//创建一个文件上传句柄---可以对factory进行设置属性FileItemFactory factory=new DiskFileItemFactory(1024*8,dir);//设置缓存的大小和位置/** *   org.apache.commons.fileupload.servlet.ServletFileUpload类是 *   Apache文件上传组件处理文件上传的核心高级类 *   (所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。 */ServletFileUpload upload=new ServletFileUpload(factory);//根据参数指定的FileItemFactory对象来创建upload.setFileSizeMax(124*1024*5);//设置每个文件最大为5Mupload.setSizeMax(1024*1024*8);//设置全部文件容量为8M//进度监听upload.setProgressListener(new ProgressListener() {/** * 1.pBytesRead 已经接收了多少字节 * 2.pContentLength 总共多少字节 * 3.pItems 第几个文件(序号从1开始) */@Overridepublic void update(long pBytesRead, long pContentLength, int pItems) {double d=pBytesRead*100/pContentLength;//得出的是百分数形式的进度值//实战时,要吧d值存入到session--表示一个用户,以让前端进度条的Ajax来读取System.out.println(d+"%");}});FileItem fi=null;//利用upload工具吧request中的数据解析出来,结果为List<FileItem>try {List<FileItem> list=upload.parseRequest(request);for(FileItem fileItem:list){fi=fileItem;if(fileItem.isFormField()){//普通表单组件//System.out.println("普通表单组件"+fileItem.getName());//解决普通表单组件的乱码问题String desc=fileItem.getString("utf-8"); //以指定编码来接收desc编辑框上传的参数//String desc=fileItem.getString();System.out.println("desc:"+desc);}else{//file组件String fileName=fileItem.getName();System.out.println("file表单组件:"+fileName);//这里是返回file组件提交的文件名//由于服务器磁盘中存储的资源文件名不能包含中文,//因此要把文件名特殊处理一下(用UUid来代替),//同时我们在引入“打散目录技术”String ext=fileName.substring(fileName.lastIndexOf("."));String uuid=UUID.randomUUID().toString().replace("-", "");fileName=uuid+ext;/** * 引入“打散目录技术”: */String dir1=Integer.toHexString(fileName.hashCode() & 0xf);String dir2=Integer.toHexString((fileName.hashCode() & 0xf0)>>4);fileName=dir1+"/"+dir2+"/"+fileName;InputStream in = fileItem.getInputStream();//上传文件的输入流//可以手动写代码进行流拷贝//这里使用appache的工具,更加方便FileUtils.copyInputStreamToFile(in, new File(path+"/"+fileName));//File file=new File(path+"/"+fileName);//File dirFile=file.getParentFile();//if(!dirFile.exists()){//dirFile.mkdir();//}//fileItem.write(file);}}} catch (FileUploadException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}finally{fi.delete();//删除临时文件}}}

原创粉丝点击